后天就是蓝桥杯省赛了,今天总结一下这段时间做的蓝桥杯历届试题,还是一个一个题目的来吧!!!!!!
1,历届试题 矩阵翻硬币
这个题目说真的,我不会,在网上看了某神牛的题解答案为 ans=sqrt(n)*sqrt(m),具体怎么证明的我也不知道
2,历届试题 兰顿蚂蚁
这个题目怎么说呢,应该是送分题,直接模拟就可以了,这里就不说了。
3, 历届试题 分糖果
这个题目好像之前在哪里做过,也是一道模拟题,弄两个数组搞一下就可以了
下面是代码
View Code
#include<bits/stdc++.h> using namespace std; #define maxn 100+10 int a[2][maxn],n; bool ok(int cur) { for (int i=2;i<=n;i++) if (a[cur][i]!=a[cur][i-1]) return 0; return 1; } int main() { while(scanf("%d",&n)!=EOF) { int cur=0,ans=0; for (int i=1;i<=n;i++) scanf("%d",&a[cur][i]); while(!ok(cur)) { for (int i=1;i<=n;i++) { if (a[cur][i]%2) { a[cur][i]++; ans++; } } for (int i=1;i<n;i++) a[1-cur][i]=a[cur][i+1]/2; a[1-cur][n]=a[cur][1]/2; for (int i=1;i<=n;i++) a[1-cur][i]+=(a[cur][i]/2); cur=1-cur; } printf("%d\n",ans); } return 0; }
4,历届试题 小朋友排队
这个题让我想起了去年武大校赛的一道题,我永远忘不了,求最小交换次数就是求逆序对数,而这个题要算出每个小朋友交换的次数,故我们从前面求一次,再从后面求一次就可以了,我这里用树状数组来求
#include<bits/stdc++.h> using namespace std; #define maxn 1000000+10 #define LL long long int a[maxn],n,b[maxn],num[maxn],c[maxn]; LL sum[maxn]; void init() { sum[0]=0; for (LL i=1;i<maxn;i++) sum[i]=sum[i-1]+i; } int lowbit(int x){ return x&(-x); } void add(int x) { while(x<maxn) { a[x]++; x+=lowbit(x); } } int get_sum(int x) { int ans=0; while(x>0) { ans+=a[x]; x-=lowbit(x); } return ans; } int main() { init(); while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); memset(num,0,sizeof(num)); for (int i=1;i<=n;i++) scanf("%d",&b[i]),c[i]=b[i]; sort(c+1,c+n+1); int m=unique(c+1,c+n+1)-c; for (int i=1;i<=n;i++) b[i]=lower_bound(c+1,c+m+1,b[i])-c; for (int i=1;i<=n;i++) { num[i]+=get_sum(maxn-1)-get_sum(b[i]); add(b[i]); } memset(a,0,sizeof(a)); for (int i=n;i>=1;i--) { num[i]+=get_sum(b[i]-1); add(b[i]); } LL ans=0; //for (int i=1;i<=n;i++) printf("%d ",num[i]); printf("\n"); for (int i=1;i<=n;i++) ans+=sum[num[i]]; printf("%I64d\n",ans); } return 0; }
5,历届试题 波动数列
这个题目一看,就知道是枚举a出现的次数和b出现的次数,网上有人用BFS和DFS来做,想都不想,肯定超时!!!!!!可以设第一个数为x,则
S=n*x+sgm i*(a or -b),则知道a和b的数目为n*(n-1)/2,则可以枚举a的数目A,知道A后,就看组成A有多少种方法,而我们只能用1,2,。。。。n-1来组成A,这不就是01背包吗?这样题目就不能了,最坏情况下时间复杂度为O(n*n^2)=n^3,但是可以的70分了,正确的解法不知道
#include<bits/stdc++.h> using namespace std; #define LL long long #define maxn 2000+100 const int mod=100000007; LL dp[2000000]; int a[maxn]; void init(int n) { for (int i=1;i<=n;i++) a[i]=i; int N=(n+1)*(n+2)/2; memset(dp,0,sizeof(dp)); dp[0]=1; for (int i=1;i<=n;i++) { for (int j=N-a[i];j>=0;j--) { if (dp[j]) dp[j+a[i]]=(dp[j+a[i]]+dp[j])%mod; } } } int main() { LL n,s,a,b; while(scanf("%I64d %I64d %I64d %I64d",&n,&s,&a,&b)!=EOF) { init(n-1); LL ans=0; LL N=n*(n-1)/2; for (LL i=0;i<=N;i++) { LL j=N-i; LL t=s-i*a+j*b; if (t%n==0) ans=(ans+dp[i])%mod; } printf("%I64d\n",ans); } return 0; }