牛客OI测试赛1
A.斐波拉契
求$f[n-1]*f[n+1]-f[n]^2$,$f[n]$為斐波拉契數列第$n$項
算一下前幾項不難發現答案為$(-1)^n$,下面用數學歸納法證明一下:
$n=2$時,猜想成立
假設$n=k$時猜想成立,即$f[k-1]*f[k+1]-f[k]^2=(-1)^k$
當$n=k$時,$f[k]f[k+2]-f[k+1]^2=f[k]
得證
#include <cstdio> #include <algorithm> #include<vector> #include<iostream> #include<cstring> char s[1000005]; using namespace std; int main(){scanf("%s",s);int l=strlen(s);int z=s[l-1]-'0';if(z%2==0)cout<<1<<endl;else cout<<-1<<endl; }#include <cstdio> #include <algorithm> #include<vector> #include<iostream> using namespace std; bool vis[10005]; int a[10005]; vector<int> ans; int main(){long long a,b;cin>>a>>b;cout<<a+b<<endl; }
C.序列
暴力就好,先求出該序列每處的前綴和,用map表示該前綴和存在,對于每次查詢,先判斷k之前是否查詢過,查詢過則不用判斷,再判斷序列和是否是k的倍數,否則,對于$1(sum/z)~k(sum/z)$的前綴和是否都存在
#include <cstdio> #include <algorithm> #include<vector> #include<iostream> #include<cstring> #include<map> using namespace std; typedef long long ll; const int maxn=100005; int ans[maxn];ll a[maxn]; map<ll,int> mp;int main(){int n,q;scanf("%d%d",&n,&q);ll sum=0;for(int i=1;i<=n;i++){scanf("%lld",&a[i]);sum+=a[i];mp[sum]=1;}for(int i=1;i<=q;i++){int z;scanf("%d",&z);if(z>n||sum%z!=0||ans[z]==2){printf("No\n");continue;}if(ans[z]==1){printf("Yes\n");continue;}for(int i=1;i*(sum/z)<sum;i++){if(mp[i*(sum/z)]!=1){printf("No\n");ans[z]=2;break;}}if(ans[z]!=2){printf("Yes\n");ans[z]=1;}} }求下直徑就好了
#include <cstdio> #include <algorithm> #include<vector> #include<iostream> #include<cstring> using namespace std; const int maxn=100005; vector< pair<int,int> > g[maxn]; int d[maxn]; bool vis[maxn]; void dfs(int u){vis[u]=1;for(int i=0;i<g[u].size();i++){int v=g[u][i].first;if(!vis[v]){d[v]=d[u]+g[u][i].second;dfs(v);}} } int main(){int n;scanf("%d",&n);for(int i=1;i<n;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);g[x].push_back(make_pair(y,z));g[y].push_back(make_pair(x,z));}// cout<<-1<<endl;dfs(1);int cnt;long long dmax=0;for(int i=1;i<=n;i++){if(d[i]>dmax){dmax=d[i];cnt=i;}vis[i]=0;d[i]=0;}dmax=0;dfs(cnt);for(int i=1;i<=n;i++){if(d[i]>dmax){dmax=d[i];}}cout<<dmax*10+(1+dmax)*dmax/2<<endl; }E.旅行青蛙
最長上升子序列,但是感覺題意有問題,題目的描述應該是最長不上升子序列233,n比較大,用$O(n*log n)$的寫法
#include <cstdio> #include <algorithm> #include<vector> #include<iostream> #include<cstring> using namespace std; const int maxn=100005; int dp[maxn]; int a[maxn]; int n; int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);int cnt=0;dp[0]=-1e9;for(int i=1;i<=n;i++){if(a[i]>=dp[cnt]){dp[++cnt]=a[i];}else {int z=upper_bound(dp+1,dp+1+cnt,a[i])-dp;dp[z]=a[i];}}cout<<cnt<<endl; }F.子序列
由題意知,答案與序列的順序無關,故先將序列排個序,對于序列中的第i個數,需要相乘的次數為$C{n-1}^{k-1}-C{i-1}^{k-1}-C_{n-i}^{k-1}$。又1e9+7為素數,根據歐拉公式$a^{p-1}\equiv1mod p$
即可得出答案
#include <cstdio> #include <algorithm> #include<vector> #include<iostream> #include<cstring> #include<map> using namespace std; typedef long long ll; const ll mod=1e9+7; const int maxn=1005;ll pmod(ll a,ll b){if(a==0) return 0;if(b==0) return 1;if(b==1) return a%mod;ll ans=pmod(a,b/2);ans=ans*ans%mod;if(b&1)return ans*a%mod;return ans; } ll a[maxn]; ll c[maxn][maxn]; int main(){for(int i=0;i<=1000;i++)c[i][0]=1;c[1][1]=1;for(int i=1;i<=1000;i++)c[i][i]=1;for(int i=1;i<=1000;i++)for(int j=1;j<i;j++)c[i][j]=(c[i-1][j]+c[i-1][j-1])%(mod-1);int t;scanf("%d",&t);while(t--){int n,k;scanf("%d%d",&n,&k);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);sort(a+1,a+1+n);ll ans=1;for(int i=2;i<n;i++){ll z=c[n-1][k-1];if(n-i>=k-1)z-=c[n-i][k-1];if(i-1>=k-1)z-=c[i-1][k-1];z=((z)%(mod-1)+mod-1)%(mod-1);z=pmod(a[i],z);ans=ans*z%mod;}printf("%lld\n",ans);}return 0; }
?
轉載于:https://www.cnblogs.com/dlutjwh/p/10976341.html
總結
- 上一篇: Django基础核心技术之Model模型
- 下一篇: 一个页面是否应该全部组件化