蓝桥杯练习(三)

青旅半醒 2023-05-28 06:45 82阅读 0赞

蓝桥杯练习(三)

      • 芯片测试
      • 分解质因数
      • 矩阵乘法
      • 矩阵乘方
      • 找零钱
      • 审美课
      • 参考博客

芯片测试

问题描述
  有n(2≤n≤20)块芯片,有好有坏,已知好芯片比坏芯片多。
  每个芯片都能用来测试其他芯片。用好芯片测试其他芯片时,能正确给出被测试芯片是好还是坏。而用坏芯片测试其他芯片时,会随机给出好或是坏的测试结果(即此结果与被测试芯片实际的好坏无关)。
  给出所有芯片的测试结果,问哪些芯片是好芯片。
输入格式
  输入数据第一行为一个整数n,表示芯片个数。
  第二行到第n+1行为n*n的一张表,每行n个数据。表中的每个数据为0或1,在这n行中的第i行第j列(1≤i, j≤n)的数据表示用第i块芯片测试第j块芯片时得到的测试结果,1表示好,0表示坏,i=j时一律为1(并不表示该芯片对本身的测试结果。芯片不能对本身进行测试)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 22;
  4. int g[MAXN][MAXN];
  5. int a[MAXN];
  6. int main(){
  7. int n;
  8. scanf("%d",&n);
  9. for(int i=0;i<n;++i){
  10. for(int j=0;j<n;++j)scanf("%d",&g[i][j]);
  11. }
  12. int t = 1<<n;//利用2进制可以进行子集选择
  13. int cnt = 0;//统计1的个数
  14. bool flag = false;//标记该方法的可行性
  15. for(int i=1;i<t;++i){
  16. for(int j=0;j<n;++j)a[j]=(i>>j)&1;
  17. cnt=0;
  18. for(int j=0;j<n;++j)if(a[j])cnt++;
  19. if(cnt<=n-cnt)continue;//好的比坏的多才满足题意
  20. flag = true;//默认可行
  21. for(int j=0;j<n;++j){
  22. if(!a[j])continue;//坏的没参考性
  23. for(int t=0;t<n;++t)if(g[j][t]!=a[t]){ flag=false;break;}
  24. if(!flag)break;
  25. }
  26. if(flag){
  27. int cntt=1;
  28. for(int j=0;j<n;++j){
  29. if(a[j]){
  30. if(cntt<cnt)printf("%d ",j+1);
  31. else printf("%d",j+1);
  32. cntt++;
  33. }
  34. }
  35. break;
  36. }
  37. }
  38. return 0;
  39. }

分解质因数

问题描述
  求出区间[a,b]中所有整数的质因数分解。
输入格式
  输入两个整数a,b。
样例输入
3 10
样例输出
3=3
4=2*2
5=5
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 105;
  4. bool vis[MAXN];
  5. int prime[MAXN],_index=0;
  6. void EuerPrime(){
  7. for (int i=2; i<MAXN; i++)
  8. {
  9. if (!vis[i]) prime[_index++]=i;
  10. for(int j=0; j<_index&&prime[j]*i<MAXN; j++)
  11. {
  12. vis[prime[j]*i]=1;
  13. if(i%prime[j]==0)break;
  14. }
  15. }
  16. }//欧拉筛法
  17. int main(){
  18. EuerPrime();
  19. int a,b,d,j,cnt;
  20. scanf("%d%d",&a,&b);
  21. for(int i=a;i<=b;++i){
  22. d = i;
  23. cnt = 0;
  24. printf("%d=",d);
  25. for(j=0;j<_index;++j){
  26. if(d<=prime[j])break;
  27. if(d%prime[j])continue;
  28. while(d%prime[j]==0){
  29. if(cnt)printf("*");
  30. printf("%d",prime[j]);
  31. cnt++;
  32. d/=prime[j];
  33. }
  34. }
  35. if(cnt&&d!=1)printf("*");
  36. if(d!=1)printf("%d",d);
  37. printf("\n");
  38. }
  39. }

矩阵乘法

问题描述
  给定一个N阶矩阵A,输出A的M次幂(M是非负整数)
  例如:
  A =
  1 2
  3 4
  A的2次幂
  7 10
  15 22
输入格式
  第一行是一个正整数N、M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数
  接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN = 32;
  5. int tmp[MAXN][MAXN]={ 0};//用来暂存结果
  6. void matrixcopy(int a[][MAXN],int b[][MAXN],int n){
  7. for(int i=0;i<n;i++)
  8. for(int j=0;j<n;j++)a[i][j]=b[i][j];
  9. }//将矩阵B的内容赋值给矩阵A
  10. // 矩阵A(n*n)*矩阵B(n*n),并且结果保留在矩阵A中
  11. void mul(int a[][MAXN],int b[][MAXN],int n){
  12. int tmp[MAXN][MAXN]={ 0};//用来暂存结果
  13. for(int i=0;i<n;i++)
  14. for(int j=0;j<n;j++)
  15. for(int k=0;k<n;k++)
  16. tmp[i][j]+=a[i][k]*b[k][j];
  17. matrixcopy(a,tmp,n);
  18. }
  19. void matrixquickpow(int a[][MAXN],int b,int n){
  20. int ans[MAXN][MAXN]={ 0};
  21. for(int i=0;i<n;i++)ans[i][i]=1;//形成单位矩阵
  22. while (b)
  23. {
  24. if(b&1)mul(ans,a,n);
  25. mul(a,a,n);
  26. b>>=1;
  27. }
  28. matrixcopy(a,ans,n);
  29. }//矩阵快速幂
  30. int t[MAXN][MAXN];
  31. int main(){
  32. int n,m;
  33. scanf("%d%d",&n,&m);
  34. for(int i=0;i<n;++i){
  35. for(int j=0;j<n;++j)scanf("%d",&t[i][j]);
  36. }
  37. matrixquickpow(t,m,n);
  38. for(int i=0;i<n;++i){
  39. for(int j=0;j<n-1;++j)printf("%d ",t[i][j]);
  40. printf("%d\n",t[i][n-1]);
  41. }
  42. }

矩阵乘方

问题描述
  给定一个矩阵A,一个非负整数b和一个正整数m,求A的b次方除m的余数。
  其中一个nxn的矩阵除m的余数得到的仍是一个nxn的矩阵,这个矩阵的每一个元素是原矩阵对应位置上的数除m的余数。
  要计算这个问题,可以将A连乘b次,每次都对m求余,但这种方法特别慢,当b较大时无法使用。下面给出一种较快的算法(用A^b表示A的b次方):
  若b=0,则A^b%m=I%m。其中I表示单位矩阵。
  若b为偶数,则Ab%m=(A(b/2)%m)^2%m,即先把A乘b/2次方对m求余,然后再平方后对m求余。
  若b为奇数,则Ab%m=(A(b-1)%m)*a%m,即先求A乘b-1次方对m求余,然后再乘A后对m求余。
  这种方法速度较快,请使用这种方法计算A^b%m,其中A是一个2x2的矩阵,m不大于10000。
输入格式
  输入第一行包含两个整数b, m,第二行和第三行每行两个整数,为矩阵A。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN = 32;
  5. int tmp[MAXN][MAXN]={ 0};//用来暂存结果
  6. void matrixcopy(int a[][MAXN],int b[][MAXN],int n){
  7. for(int i=0;i<n;i++)
  8. for(int j=0;j<n;j++)a[i][j]=b[i][j];
  9. }//将矩阵B的内容赋值给矩阵A
  10. // 矩阵A(n*n)*矩阵B(n*n),并且结果保留在矩阵A中
  11. void mul(int a[][MAXN],int b[][MAXN],int n,int m){
  12. int tmp[MAXN][MAXN]={ 0};//用来暂存结果
  13. for(int i=0;i<n;i++)
  14. for(int j=0;j<n;j++)
  15. for(int k=0;k<n;k++)
  16. tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%m;
  17. matrixcopy(a,tmp,n);
  18. }
  19. void matrixquickpow(int a[][MAXN],int b,int n,int m){
  20. int ans[MAXN][MAXN]={ 0};
  21. for(int i=0;i<n;i++)ans[i][i]=1;//形成单位矩阵
  22. while (b)
  23. {
  24. if(b&1)mul(ans,a,n,m);
  25. mul(a,a,n,m);
  26. b>>=1;
  27. }
  28. matrixcopy(a,ans,n);
  29. for(int i=0;i<n;++i){
  30. for(int j=0;j<n;++j)a[i][j]%=m;//当b=0
  31. }
  32. }//矩阵快速幂
  33. int t[MAXN][MAXN];
  34. int main(){
  35. int n=2,b,m;
  36. scanf("%d%d",&b,&m);
  37. for(int i=0;i<n;++i){
  38. for(int j=0;j<n;++j)scanf("%d",&t[i][j]);
  39. }
  40. matrixquickpow(t,b,n,m);
  41. for(int i=0;i<n;++i){
  42. for(int j=0;j<n-1;++j)printf("%d ",t[i][j]);
  43. printf("%d\n",t[i][n-1]);
  44. }
  45. }

找零钱

问题描述
  有n个人正在饭堂排队买海北鸡饭。每份海北鸡饭要25元。奇怪的是,每个人手里只有一张钞票(每张钞票的面值为25、50、100元),而且饭堂阿姨一开始没有任何零钱。请问饭堂阿姨能否给所有人找零(假设饭堂阿姨足够聪明)
输入格式
  第一行一个整数n,表示排队的人数。
  接下来n个整数a[1],a[2],…,a[n]。a[i]表示第i位学生手里钞票的价值(i越小,在队伍里越靠前)
输出格式
  输出YES或者NO

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int main(){
  4. int n,a=0,b=0,d;//总数,25,50
  5. scanf("%d",&n);
  6. for(int i=0;i<n;++i){
  7. scanf("%d",&d);
  8. if(d==25)a++;
  9. else if(d==50){
  10. a--;
  11. if(a<0){
  12. printf("NO");
  13. return 0;
  14. }
  15. b++;
  16. }else{
  17. if(b==0){
  18. a-=2;
  19. }else {
  20. a--;
  21. b--;
  22. }
  23. if(a<0){
  24. printf("NO");
  25. return 0;
  26. }
  27. }
  28. }
  29. printf("YES");
  30. return 0;
  31. }

审美课

问题描述
  《审美的历程》课上有n位学生,帅老师展示了m幅画,其中有些是梵高的作品,另外的都出自五岁小朋友之手。老师请同学们分辨哪些画的作者是梵高,但是老师自己并没有答案,因为这些画看上去都像是小朋友画的……老师只想知道,有多少对同学给出的答案完全相反,这样他就可以用这个数据去揭穿披着皇帝新衣的抽象艺术了(支持帅老师_)。
  答案完全相反是指对每一幅画的判断都相反。
输入格式
  第一行两个数n和m,表示学生数和图画数;
  接下来是一个n*m的01矩阵A:
  如果aij=0,表示学生i觉得第j幅画是小朋友画的;
  如果aij=1,表示学生i觉得第j幅画是梵高画的。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int x[1<<20];
  4. int main()//利用2进制
  5. {
  6. int n,m,d,ans=0;
  7. scanf("%d%d",&n,&m);
  8. const int N =(1<<m)-1;
  9. for(int i=0;i<n;++i){
  10. int sum1=0,sum2=0;
  11. for(int j=0;j<m;++j){
  12. scanf("%d",&d);
  13. sum1=(sum1<<1)+d;//注意优先级
  14. }
  15. x[sum1]++;
  16. ans+=x[sum1^N];
  17. }
  18. printf("%d\n",ans);
  19. }

参考博客

  • 蓝桥杯练习(一)
  • 蓝桥杯练习(二)

发表评论

表情:
评论列表 (有 0 条评论,82人围观)

还没有评论,来说两句吧...

相关阅读