sihai的博客

life is always beautiful like sunshine

蓝桥杯练习系统习题-算法训练3

文章推荐

蓝桥杯练习系统习题-算法训练3

题目搜索方式:Ctrl+F—-> 输入题目名称—>定位到解答.

入门训练(详见 算法-蓝桥杯习题(1-1))

基础练习(详见 算法-蓝桥杯习题(2-1))

基础练习(详见 算法-蓝桥杯习题(2-2))

算法训练(详见 算法-蓝桥杯习题(3-1))

算法训练(详见 算法-蓝桥杯习题(3-2))

算法训练(详见 算法-蓝桥杯习题(3-3))

算法训练(详见 算法-蓝桥杯习题(3-4))

算法训练(详见 算法-蓝桥杯习题(3-5))

算法训练(详见 算法-蓝桥杯习题(3-6))

算法提高(详见 算法-蓝桥杯习题(4-1))

算法提高(详见 算法-蓝桥杯习题(4-2))

历届试题(详见 算法-蓝桥杯习题(5-1))

历届试题(详见 算法-蓝桥杯习题(5-2))


算法训练 弹弹堂

问题描述
  XX无聊玩弹弹堂,战斗力太低啦!
输入格式
  测试数据的输入一定会满足的格式。
  例:输入的第一行包含两个整数n, m,分别表示矩阵的行数和列数。接下来n行,每行m个正整数,表示输入的矩阵。
输出格式
  要求用户的输出满足的格式。
  例:输出1行,包含一个整数,表示矩阵中所有元素的和。
样例输入
一个满足题目要求的输入范例。
例:
2 2
1 2
3 4
样例输出
与上面的样例输入对应的输出。
例:
10
数据规模和约定
  输入数据中每一个数的范围。
  例:0<n,m<100, 0<=矩阵中的每个数<=1000。

 #include<stdio.h>  
 main()  
 {  
     printf("1.54545");  
     return 0;  
 }  

算法训练 送分啦

问题描述
  这题想得分吗?想,请输出“yes”;不想,请输出“no”。
输出格式
  输出包括一行,为“yes”或“no”。

#include <stdio.h>  
 main()  
 {  
    printf("yes\n");  
    return 0;  
 }  

算法训练 A+B Problem

问题描述
  输入A,B。
  输出A+B。
输入格式
  输入包含两个整数A,B,用一个空格分隔。
输出格式
  输出一个整数,表示A+B的值。
样例输入
5 8
样例输出
13
数据规模和约定
  -1,000,000,000<=A,B<=1,000,000,000。

 #include <stdio.h>  
 main()  
 {  
     long long int A,B;  
     scanf("%lld%lld",&A,&B);  
     printf("%lld\n",A+B);  
     return 0;  
 }  

算法训练 采油区域

采油区域  Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井。被拍卖的整块土地为一个矩形区域,被划分为M×N个小块。
  Siruseri地质调查局有关于Navalur土地石油储量的估测数据。这些数据表示为M×N个非负整数,即对每一小块土地石油储量的估计值。
  为了避免出现垄断,政府规定每一个承包商只能承包一个由K×K块相连的土地构成的正方形区域。
  AoE石油联合公司由三个承包商组成,他们想选择三块互不相交的K×K的区域使得总的收益最大。
  例如,假设石油储量的估计值如下:

无图

  如果K = 2, AoE公司可以承包的区域的石油储量总和为100, 如果K = 3, AoE公司可以承包的区域的石油储量总和为208。
  AoE公司雇佣你来写一个程序,帮助计算出他们可以承包的区域的石油储量之和的最大值。
输入格式
  输入第一行包含三个整数M, N, K,其中M和N是矩形区域的行数和列数,K是每一个承包商承包的正方形的大小(边长的块数)。接下来M行,每行有N个非负整数表示这一行每一小块土地的石油储量的估计值。
输出格式
  输出只包含一个整数,表示AoE公司可以承包的区域的石油储量之和的最大值。
数据规模和约定
  数据保证K≤M且K≤N并且至少有三个K×K的互不相交的正方形区域。其中30%的输入数据,M, N≤ 12。所有的输入数据, M, N≤ 1500。每一小块土地的石油储量的估计值是非负整数且≤ 500。
样例输入
9 9 3
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 8 8 8 8 8 1 1 1
1 8 8 8 8 8 1 1 1
1 8 8 8 8 8 1 1 1
1 1 1 1 8 8 8 1 1
1 1 1 1 1 1 8 8 8
1 1 1 1 1 1 9 9 9
1 1 1 1 1 1 9 9 9
样例输出
208

 #include <cstdio>  
 #include <cstdlib>  
 #include <algorithm>  
 #include <string>  
 #define max(a, b) ((a) > (b) ? (a) : (b))  
 #define max3(a, b, c) (max((a), max(b, c)))  
 const char fi[] = "oil.in";  
 const char fo[] = "oil.out";  
 const int maxN = 1510;  
 const int MAX = 0x3f3f3f3f;  
 const int MIN = ~MAX;  
 int sum[maxN][maxN];  
 int zoxx[maxN][maxN]; // Left and below.  
 int zouh[maxN][maxN]; // Left and above.  
 int yzxx[maxN][maxN]; // Right and below.  
 int yzuh[maxN][maxN]; // Right and above.  
 int hh[maxN]; // Horizon.  
 int lp[maxN]; // Vertical.  
 int n,m,K;  
 void init_file()  
 {  
     return;  
 }  
 inline int getint()  
 {  
     int res = 0; char tmp;  
     while(!isdigit(tmp = getchar()));  
     do res = (res << 3) + (res << 1) + tmp - '0';  
     while(isdigit(tmp = getchar()));  
     return res;  
 }  
 void readdata()  
 {  
     n = getint(); m = getint(); K = getint();  
     for(int i = 1; i < n + 1; ++i)  
         for(int j = 1; j < m + 1; ++j)  
             (sum[i][j] = getint()) += sum[i][j - 1];  
     for(int i = 1; i < n + 1; ++i)  
         for(int j = 1; j < m + 1; ++j)  
             sum[i][j] += sum[i - 1][j];  
     //预处理出二维的前缀和。  
     for(int i = K; i < n + 1; ++i)  
         for(int j = K; j < m + 1; ++j)  
         {  
             zouh[i][j] = sum[i][j]  
                 + sum[i - K][j - K]  
                 - sum[i][j - K]  
                 - sum[i - K][j];  
             hh[i] = max(hh[i],zouh[i][j]); //Horizon.  
             lp[j] = max(lp[j],zouh[i][j]); //Vertical.  
             zouh[i][j] = max3(zouh[i][j],  
                 zouh[i - 1][j],  
                 zouh[i][j - 1]);  
         } // Left and above.  
     for(int i = n - K + 1; i; --i)  
         for(int j = m - K + 1; j; --j)  
             yzxx[i][j] = max3(sum[i - 1][j - 1]  
             + sum[i + K - 1][j + K - 1]  
             - sum[i - 1][j + K - 1]  
             - sum[i + K - 1][j - 1],  
             yzxx[i + 1][j],  
             yzxx[i][j + 1]);  
     //Right and below.  
     for(int i = K; i < n + 1; ++i)  
         for(int j = m - K + 1; j; --j)  
             yzuh[i][j] = max3(sum[i][j + K - 1]  
             + sum[i - K][j - 1]  
             - sum[i][j - 1]  
             - sum[i - K][j + K - 1],  
             yzuh[i - 1][j],  
             yzuh[i][j + 1]);  
     //Right and above.  
     for(int i = n - K + 1; i; --i)  
         for(int j = K; j < m + 1; ++j)  
             zoxx[i][j] = max3(sum[i - 1][j - K]  
             + sum[i + K - 1][j]  
             - sum[i - 1][j]  
             - sum[i + K - 1][j - K],  
             zoxx[i + 1][j],  
             zoxx[i][j - 1]);  
     //Left and below  
     return;  
 }  
 void work()  
 {  
     int ans = 0;  
     for(int i = K; i < n - (K << 1); ++i)  
         ans = max(ans,yzuh[i][1]  
         + hh[i + K]  
         + yzxx[i + K + 1][1]);  
     // Case 1.  
     for(int j = K; j < m - (K << 1); ++j)  
         ans = max(ans,zoxx[1][j]  
         + lp[j + K]  
         + yzxx[1][j + K + 1]);  
     // Case 2.  
     for(int i = K; i < n - K + 1; ++i)  
         for(int j = K; j < m - K + 1; ++j)  
         {  
             ans = max3(ans,zouh[i][j]  
                 + yzuh[i][j + 1]  
                 + yzxx[i + 1][1], //Case 3.  
                 yzuh[i][1]  
                 + zoxx[i + 1][j]  
                 + yzxx[i + 1][j + 1]); //Case 4.  
             ans = max3(ans,zouh[i][j]  
                 + zoxx[i + 1][j]  
                 + yzxx[1][j + 1], //Case 5.  
                 zoxx[1][j]  
                 + yzuh[i][j + 1]  
                 + yzxx[i + 1][j + 1]); //Case 6.  
         }  
     printf("%d\n",ans);  
     return;  
 }  
 int main()  
 {  
     init_file();  
     readdata();  
     work();  
     return 0;  
 }  
 #undef max  

算法训练 调和数列问题

问题描述
  输入一个实数x,求最小的n使得,1/2+1/3+1/4+…+1/(n+1)>=x。

  输入的实数x保证大于等于0.01,小于等于5.20,并且恰好有两位小数。你的程序要能够处理多组数据,即不停地读入x,如果x不等于0.00,则计算答案,否则退出程序。

  输出格式为对于一个x,输出一行n card(s)。其中n表示要计算的答案。
输入格式
  分行输入x的具体数值
输出格式
  分行输出n的数值,格式为n card(s)
样例输入
1.00
3.71
0.04
5.19
0.00

样例输出

3 card(s)
61 card(s)
1 card(s)
273 card(s)

#include<stdio.h>  
 int main(void)  
 {  
     int i;  
     double n,k,s;  
     scanf("%lf",&n);  
     while(n!=0)  
     {  
         s=0;  
         for(i=2;1;i++)  
         {  
             k=1.0/i;  
             s+=k;  
             if(s>=n)  
             {  
                 printf("%d card(s)\n",i-1);  
                 break;  
             }  
         }  
         scanf("%lf",&n);  
     }  
     return 0;  
 }  

算法训练 Hanoi问题

问题描述
  如果将课本上的Hanoi塔问题稍做修改:仍然是给定N只盘子,3根柱子,但是允许每次最多移动相邻的M只盘子(当然移动盘子的数目也可以小于M),最少需要多少次?
  例如N=5,M=2时,可以分别将最小的2个盘子、中间的2个盘子以及最大的一个盘子分别看作一个整体,这样可以转变为N=3,M=1的情况,共需要移动7次。
输入格式
  输入数据仅有一行,包括两个数N和M(0<=M<=N<=8)
输出格式
  仅输出一个数,表示需要移动的最少次数
样例输入
5 2

样例输出

7

 #include <stdio.h>  
 int main()  
 {  
     int N,M;  
     scanf("%d%d",&N,&M);  
     N=(N+1)/M;  
     printf("%d",(1<<N)-1);  
     return 0;  
 }  

汉若塔

说明河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。
解法如果柱子标为ABC,要由A搬至C,在只有一个盘子时,就将它直接搬至C,当有两个盘子,就将B当作辅助柱。如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两个盘子,也就是:A->B、A ->C、B->C这三个步骤,而被遮住的部份,其实就是进入程式的递回处理。事实上,若有n个盘子,则移动完毕所需之次数为2^n - 1,所以当盘数为64时,则所需次数为:264- 1 = 18446744073709551615为5.05390248594782e+16年,也就是约5000世纪,如果对这数字没什幺概念,就假设每秒钟搬一个盘子好了,也要约5850亿年左右。

#include <stdio.h>  
 void hanoi(int n, char A, char B, char C) {  
     if(n == 1) {  
         printf("Move sheet %d from %c to %c\n", n, A, C);  
     }  
     else {  
         hanoi(n-1, A, C, B);  
         printf("Move sheet %d from %c to %c\n", n, A, C);  
         hanoi(n-1, B, A, C);  
     }  
 }  
 int main() {  
     int n;  
     printf("请输入盘数:");  
     scanf("%d", &n);  
     hanoi(n, 'A', 'B', 'C');  
     return 0;  
 }  

算法训练 蜜蜂飞舞

问题描述
  “两只小蜜蜂呀,飞在花丛中呀……”

  话说这天天上飞舞着两只蜜蜂,它们在跳一种奇怪的舞蹈。用一个空间直角坐标系来描述这个世界,那么这两只蜜蜂初始坐标分别为(x1,y1,z1),(x2,y2,z2)  。在接下来它们将进行n次飞行,第i次飞行两只蜜蜂分别按照各自的速度向量飞行ti个单位时间。对于这一现象,玮玮已经观察了很久。他很想知道在蜜蜂飞舞结束时,两只蜜蜂的距离是多少。现在他就求教于你,请你写一个程序来帮他计算这个结果。
输入格式
  第一行有且仅有一个整数n,表示两只蜜蜂将进行n次飞行。

  接下来有n行。

  第i行有7个用空格分隔开的整数ai,bi,ci,di,ei,fi,ti  ,表示第一只蜜蜂单位时间的速度向量为(ai,bi,ci) ,第二只蜜蜂单位时间的速度向量为(di,ei,fi) ,它们飞行的时间为ti 。

  最后一行有6个用空格分隔开的整数x1,y1,z1,x2,y2,z2,如题所示表示两只蜜蜂的初始坐标。
输出格式
  输出仅包含一行,表示最后两只蜜蜂之间的距离。保留4位小数位。
样例输入
Sample 1
1
1 1 1 1 -1 1 2
3 0 1 2 0 0
Sample 2
3
1 1 1 1 -1 1 2
2 1 2 0 -1 -1 2
2 0 0 -1 1 1 3
3 0 1 2 0 0

样例输出

Sample 1
4.2426
Sample 2
15.3948

 #include <stdio.h>  
 #include <math.h>  
 int main()  
 {  
     int n;  
     double x1=0,y1=0,z1=0,x2=0,y2=0,z2=0;  
     int ai,bi,ci,di,ei,fi,ti;  
     int i;  
     scanf("%d",&n);  
     for(i=0;i<n;i++)  
     {  
         scanf("%d%d%d%d%d%d%d",&ai,&bi,&ci,&di,&ei,&fi,&ti);  
         x1+=ai*ti;  
         y1+=bi*ti;  
         z1+=ci*ti;  
         x2+=di*ti;  
         y2+=ei*ti;  
         z2+=fi*ti;  
     }  
     scanf("%d%d%d%d%d%d",&ai,&bi,&ci,&di,&ei,&fi);  
     x1+=ai;  
     y1+=bi;  
     z1+=ci;  
     x2+=di;  
     y2+=ei;  
     z2+=fi;   
     printf("%.4lf",sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));  
     return 0;  
 }  

算法训练 关联矩阵

问题描述
  有一个n个结点m条边的有向图,请输出他的关联矩阵。
输入格式
  第一行两个整数n、m,表示图中结点和边的数目。n<=100,m<=1000。
  接下来m行,每行两个整数a、b,表示图中有(a,b)边。
  注意图中可能含有重边,但不会有自环。
输出格式
  输出该图的关联矩阵,注意请勿改变边和结点的顺序。
样例输入
5 9
1 2
3 1
1 5
2 5
2 3
2 3
3 2
4 3
5 4
样例输出
1 -1 1 0 0 0 0 0 0
-1 0 0 1 1 1 -1 0 0
0 1 0 0 -1 -1 1 -1 0
0 0 0 0 0 0 0 1 -1
0 0 -1 -1 0 0 0 0 1

 #include<stdio.h>  
 int main()  
 {  
     int i, ii,n,m, a[1000][2];  
     scanf("%d%d", &n, &m);  
     for (  i = 0; i < m; i++)  
     scanf("%d%d", &a[i][0], &a[i][1]);  
     for ( i = 1; i <=n; i++)  
     {  
         for (ii = 0; ii < m; ii++)  
         {  
             if (i==a[ii][0])  
             {  
                 printf("1 ");  
             }  
             else  
             if (i==a[ii][1])  
             {  
                 printf("-1 ");  
             }  
             else  
             {  
                 printf("0 ");  
             }  
         }  
         printf("\n");  
     }  
     return 0;  
 }  

算法训练 寻找数组中最大值

问题描述
  对于给定整数数组a[],寻找其中最大值,并返回下标。
输入格式
  整数数组a[],数组元素个数小于1等于100。输出数据分作两行:第一行只有一个数,表示数组元素个数;第二行为数组的各个元素。
输出格式
  输出最大值,及其下标
样例输入
33 2 1
样例输出
3 0

 #include <stdio.h>  
 #define MaxSize 100+5  
 main()  
 {  
     int a[MaxSize],n;  
     int i,flag,max;  
     scanf("%d",&n);  
     for(i=0;i<n;i++)  
     {  
         scanf("%d",&a[i]);  
         if(i==0)  
         {  
             max=a[i];  
             flag=i;  
         }  
         if(a[i]>max)  
         {  
             max=a[i];  
             flag=i;  
         }  
     }  
     printf("%d %d\n",max,flag);  
     return 0;  
 }  

算法训练 数组查找及替换

问题描述
  给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素,同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z的ASCII之间,替换为对应字母。元素个数不超过100,b在1至100之间。
输入格式
  第一行为数组元素个数和整数b
  第二行为数组各个元素
输出格式
  按照要求输出
样例输入
7 2
77 11 66 22 44 33 55

样例输出

11 33 55 M

 #include <stdio.h>   
 #include <stdlib.h>   
 void del(int a[],int *len,int m)   
 {   
     int i,j;   
     for(i=0;i<*len;i++)   
         if(a[i]%m==0)   
         {   
             for(j=i;j<*len;j++)   
                 a[j]=a[j+1];   
             (*len)--;   
             i--;   
         }   
 }   
 int cmp(const void *a,const void *b)   
 {   
     return *(int *)a-*(int *)b;   
 }    
 int main()   
 {   
     int a[101]={},i,m,n;   
     scanf("%d%d",&n,&m);   
     for(i=0;i<n;i++)   
         scanf("%d",&a[i]);   
     del(a,&n,m);   
     qsort(a,n,sizeof(a[0]),cmp);   
     for(i=0;i<n;i++)   
     {   
         if(a[i]>=65&&a[i]<=90)   
             printf("%c ",a[i]);   
         else   
             printf("%d ",a[i]);   
     }   
    return 0;   
 }   

算法训练 Torry的困惑(基本型)

问题描述
  Torry从小喜爱数学。一天,老师告诉他,像2、3、5、7……这样的数叫做质数。Torry突然想到一个问题,前10、100、1000、10000……个质数的乘积是多少呢?他把这个问题告诉老师。老师愣住了,一时回答不出来。于是Torry求助于会编程的你,请你算出前n个质数的乘积。不过,考虑到你才接触编程不久,Torry只要你算出这个数模上50000的值。
输入格式
  仅包含一个正整数n,其中n<=100000。
输出格式
  输出一行,即前n个质数的乘积模50000的值。
样例输入
1
样例输出
2
思路二:递归

 #include <stdio.h>  
 int isPrime(int num)  
 {  
     int i;  
     //此题不牵扯到1   
     if(num==1)  
     {  
         return 0;  
     }  
     for(i=2;i*i<num+1;i++)  
     {  
         //能被其区间(2,sqrt(num+1))整除的数不是质数   
         if(num%i==0)  
         {  
             return 0;  
         }  
     }  
     return 1;  
 }  
 int getNextPrime(int num)  
 {  
     //取下一个数 ,直到得出结果   
     while(++num)  
     {  
         //判断num,如果是质数则返回此值   
         if(isPrime(num))  
         {  
             return num;  
         }  
     }  
     return 0;  
 }  
 int getResult(int n)  
 {  
     int result=1,next=2;  
     while(n--)  
     {  
         //printf("result_value:%d\n",result);//测试结果   
         //printf("next_value:%d\n",next);//测试下一质数   
         //结果累计   
         result=result*next%50000;  
         //获得next的下一质数   
         next=getNextPrime(next);  
     }  
     return result;  
 }  
 main()  
 {  
     int n;  
     scanf("%d",&n);  
     printf("%d\n",getResult(n));  
     return 0;  
 }  

算法训练 排列问题

问题描述
  求一个0~N-1的排列(即每个数只能出现一次),给出限制条件(一张N*N的表,第i行第j列的1或0,表示为j-1这个数不能出现在i-1这个数后面,并保证第i行第i列为0),将这个排列看成一个自然数,求从小到大排序第K个排列。
数据规模和约定
  N<=10,K<=500000
输入格式
  第一行为N和K,接下来的N行,每行N个数,0表示不能,1表示能
输出格式
  所求的排列
样例输入
3 2
0 1 1
1 0 0
0 1 0

样例输出

1 0 2
解释:
对于N=3的没有任何限制的情况
第一:0 1 2
第二:0 2 1
第三:1 0 2
第四:1 2 0
第五:2 0 1
第六:2 1 0
根据题目所给的限制条件由于2不能出现在1后面,0不能出现在2后面
第一:0 2 1
第二:1 0 2
第三:2 1 0

 #include "iostream"  
 #include "string"  
 #include "stdio.h"  
 #include "ctype.h"  
 #include "algorithm"  
 #include "stack"  
 using namespace std;  
 const  int N =101;  
 int a[11];  
  bool  map[11][11];  
 bool isOk(int n)  
 {  
     for(int i=0;i<n-1;i++)  
             if(map[ a[i] ][ a[i+1] ] == 0)  
             {  
                 return false;  
             }  
         return true;  
 }  
 void init()  
 {  
     for(int i=0;i<10;i++)  
         a[i]=i;  
 }  
 int main()  
 {  
      int n;  
      int k;  
      cin>>n>>k;  
      for(int i=0;i<n;i++)  
          for(int j = 0; j < n; j++)  
              cin>>map[i][j];  
      init();  
      int num=0;  
      do   
      {  
         if(isOk(n))  
             num++;  
         if(num==k)  
         {  
             cout<<a[0];  
             for(int i=1;i<n;i++)  
                 cout<<" "<<a[i];  
             cout<<endl;  
             break;  
         }  
          //cout<<endl;  
      } while (std::next_permutation(a,a+n));  
 }  

算法训练 最小乘积(基本型)

问题描述
  给两组数,各n个。
  请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加

的和最小。要求程序输出这个最小值。
  例如两组数分别为:1 3  -5和-2 4 1

  那么对应乘积取和的最小值应为:
  (-5) * 4 + 3 * (-2) + 1 * 1 = -25
输入格式
  第一个行一个数T表示数据组数。后面每组数据,先读入一个n,接下来两行

每行n个数,每个数的绝对值小于等于1000。
  n<=8,T<=1000
输出格式
  一个数表示答案。
样例输入
231 3 -5-2 4 151 2 3 4 51 0 1 0 1
样例输出
-256

#include <stdio.h>  
 #define MaxSize 8+5  
 //数组排序-序列从大到小   
 void BubbleSort(int num[],int Size)  
 {  
     int i,j;  
     int temp;  
     for(i=Size-1;i>0;i--)  
     {  
         for(j=0;j<i;j++)  
         {  
             if(num[j]<num[j+1])  
             {  
                 temp=num[j];  
                 num[j]=num[j+1];  
                 num[j+1]=temp;  
             }  
         }  
     }  
 }  
 main()  
 {  
     int T,n,i;  
     int a[MaxSize],b[MaxSize];   
     scanf("%d",&T);  
     while(T--)  
     {  
         int sum=0;  
         scanf("%d",&n);  
         for(i=0;i<n;i++)  
         {  
             scanf("%d",&a[i]);  
         }  
         for(i=0;i<n;i++)  
         {  
             scanf("%d",&b[i]);  
         }  
         //数组大到小排序   
         BubbleSort(a,n);  
         BubbleSort(b,n);  
         for(i=0;i<n;i++)  
         {  
             sum+=a[i]*b[n-1-i];  
         }  
         printf("%d\n",sum);  
     }  
     return 0;  
 }  

算法训练 简单加法(基本型)

问题描述
  首先给出简单加法算式的定义:
  如果有一个算式(i)+(i+1)+(i+2),(i>=0),在计算的过程中,没有任何一个数位出现了进位,则称其为简单的加法算式。
  例如:i=3时,3+4+5=12,有一个进位,因此3+4+5不是一个简单的加法算式;又如i=112时,112+113+114=339,没有在任意数位上产生进位,故112+113+114是一个简单的加法算式。

  问题:给定一个正整数n,问当i大于等于0且小于n时,有多少个算式(i)+(i+1)+(i+2)是简单加法算式。其中n<10000。
输入格式
  一个整数,表示n
输出格式
  一个整数,表示简单加法算式的个数
样例输入
4

样例输出

3

 #include<stdio.h>  
 int main(void)  
 {  
     int n,i;  
     int count=0;  
     int a,b,c,d;  
     scanf("%d",&n);  
     for(i=0;i<n;i++)  
     {  
         d=i%10;  
         c=i/10%10;  
         b=i/100%10;  
         a=i/1000;  
         if(a<=2&&b<=2&&c<=2&&d<=2)  
             count++;  
     }  
     printf("%d",count);  
     return 0;  
 }  

算法训练 矩阵加法

问题描述
  给定两个N×M的矩阵,计算其和。其中:
  N和M大于等于1且小于等于100,矩阵元素的绝对值不超过1000。
输入格式
  输入数据的第一行包含两个整数N、M,表示需要相加的两个矩阵的行数和列数。接下来2N行每行包含M个数,其中前N行表示第一个矩阵,后N行表示第二个矩阵。 输出格式   你的程序需要输出一个NM的矩阵,表示两个矩阵相加的结果。注意,输出中每行的最后不应有多余的空格,否则你的程序有可能被系统认为是Presentation  Error
样例输入
2 2
1 2
3 4
5 6
7 8

样例输出

6 8
10 12

 #include<stdio.h>  
 int main(void)  
 {  
     static int a[100][100],b[100][100];   
     int n,m;  
     int i,j;  
     scanf("%d%d",&n,&m);  
     for(i=0;i<n;i++)  
         for(j=0;j<m;j++)  
             scanf("%d",&a[i][j]);  
     for(i=0;i<n;i++)  
         for(j=0;j<m;j++)  
             scanf("%d",&b[i][j]);  
     for(i=0;i<n;i++)  
     {  
         for(j=0;j<m;j++)  
         {  
             a[i][j]+=b[i][j];  
             printf("%d ",a[i][j]);  
         }  
         printf("\n");  
     }  
     return 0;  
 }  

算法训练 邮票

问题描述
  给定一个信封,有N(1≤N≤100)个位置可以贴邮票,每个位置只能贴一张邮票。我们现在有M(M<=100)种不同邮资的邮票,面值为X1,X2….Xm分(Xi是整数,1≤Xi≤255),每种都有N张。

  显然,信封上能贴的邮资最小值是min(X1, X2, …, Xm),最大值是 N*max(X1, X2, …,  Xm)。由所有贴法得到的邮资值可形成一个集合(集合中没有重复数值),要求求出这个集合中是否存在从1到某个值的连续邮资序列,输出这个序列的最大值。

  例如,N=4,M=2,面值分别为4分,1分,于是形成1,2,3,4,5,6,7,8,9,10,12,13,16的序列,而从1开始的连续邮资序列为1,2,3,4,5,6,7,8,9,10,所以连续邮资序列的最大值为10分。
输入格式
  第一行:最多允许粘贴的邮票张数N;第二行:邮票种数M;第三行:空格隔开的M个数字,表示邮票的面值Xi。注意:Xi序列不一定是大小有序的!
输出格式
  从1开始的连续邮资序列的最大值MAX。若不存在从1分开始的序列(即输入的邮票中没有1分面额的邮票),则输出0.
样例输入
样例一:
4
2
4 1
样例二:
10
5
2 4 6 8 10

样例输出

样例一:
10
样例二:
0

 #include<stdio.h>  
 #include<string.h>  
 int main()  
 {  
     int N,M,i,Max,zuixiaozhi,t,found;//N个位置。M种邮资   
     int youzi[260];  
     int dp[26000];  
     scanf("%d %d",&N,&M);   
     for(i=0;i<M;i++)  
     {  
         scanf("%d",&youzi[i]);  
     }  
     memset(dp,0,sizeof(dp));  
     Max=0;  
     while(1)  
     {  
         Max++;  
         found=0;  
         zuixiaozhi=10000000;  
         for(i=0;i<M;i++)  
         {  
             t=Max-youzi[i];  
             if(t>=0&&dp[t]+1<zuixiaozhi)  
             {  
                 dp[Max]=dp[t]+1;  
                 zuixiaozhi=dp[t]+1;  
                 found=1;  
             }  
         }   
         //printf("%d\n",dp[Max]);  
         if(dp[Max]>N||found==0)  
         {  
             printf("%d\n",Max-1);  
             break;  
         }  
     }   
     return 0;  
 }   

算法训练 删除多余括号

问题描述
  从键盘输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简。另外不考虑'+'  '-'用作正负号的情况,即输入表达式不会出现(+a)或(-a)的情形。
输入格式
  表达式字符串,长度不超过255,  并且不含空格字符。表达式中的所有变量都是单个小写的英文字母, 运算符只有加+减-乘除/等运算符号。 输出格式   去掉多余括号后的表达式 样例输入 样例一: a+(b+c)-d 样例二: a+b/(c+d) 样例三: (ab)+c/d
样例四:
((a+b)*f)-(i/j)

样例输出

样例一:
a+b+c-d
样例二:
a+b/(c+d)
样例三:
ab+c/d 样例四: (a+b)f-i/j

 #include <stdio.h>  
 int q(char *ch)  
 {  
     int i=0,z=0;  
     ch[i] = '#';  
     while (ch[i] != ')'||z!=0)  
     {  
         if (ch[i]=='(')  
         {  
             z++;  
         }  
         if (ch[i]==')')  
         {  
             z--;  
         }  
         i++;  
     }  
     ch[i] = '#';  
     return i;  
 }  
 int f(char *ch, char a)  
 {  
     int i = 0,jj=0;  
     if (a == '+')  
     {  
         while (ch[i] != ')')  
         {  
             if (ch[i+1] == '(')  
             if (f(&ch[i], ch[i - 1]) == 0)  
                 i += q(&ch[i]);  
             else  
             {  
                 while (ch[i] != ')')  
                 {  
                     i++;  
                 }  
             }  
             i++;  
         }  
         if (ch[i + 1] == '*' || ch[i + 1] == '/')  
         {  
             return 1;  
         }  
         else  
         {  
             return 0;  
         }  
     }  
     if (a == '-')  
     {  
         while (ch[i] != ')')  
         {  
             if (ch[i] == '(')  
             if (f(&ch[i+1], ch[i - 1]) == 0)  
                 i += q(&ch[i]);  
             else  
             {  
                 while (ch[i] != ')')  
                 {  
                     i++;  
                 }  
             }  
             if (ch[i] == '+' || ch[i] == '-')  
                 return 1;  
             i++;  
         }  
         if (ch[i + 1] == '*' || ch[i + 1] == '/')  
         {  
             return 1;  
         }  
         else  
         {  
             return 0;  
         }  
     }  
     if (a == '*')  
     {  
         while (ch[i] != ')')  
         {  
             if (ch[i] == '(')  
             if (f(&ch[i+1], ch[i - 1]) == 0)  
                 q(&ch[i]);  
             else  
             {  
                 while (ch[i] != ')')  
                 {  
                     i++;  
                 }  
             }  
             if (ch[i] == '+' || ch[i] == '-')  
                 return 1;  
             i++;  
         }  
         return 0;  
     }  
     if (a == '/')  
     {  
         while (ch[i] != ')')  
         {  
             if (ch[i] == '(')  
             if (f(&ch[i+1], ch[i - 1]) == 0)  
                 q(&ch[i]);  
             else  
             {  
                 while (ch[i] != ')')  
                 {  
                     i++;  
                 }  
             }  
             if (ch[i] == '+' || ch[i] == '-' || ch[i] == '/' || ch[i] == '*')  
                 return 1;  
             i++;  
         }  
     }  
     while (ch[i] != ')')  
     {  
         if (ch[i] == '(')  
         if (f(&ch[i+1], ch[i - 1]) == 0)  
             i += q(&ch[i]);  
         else  
         {  
             while (ch[i] != ')')  
             {  
                 i++;  
             }  
         }  
         if (ch[i] == '+' || ch[i] == '-')  
             jj=1;  
         i++;  
     }  
     if ((ch[i + 1] == '*' || ch[i + 1] == '/')&&jj==1)  
     {  
         return 1;  
     }  
     else  
     {  
         return 0;  
     }  
 }  
 void g(char *a)  
 {  
     int i = 0;  
     while (a[i]!='\0')  
     {  
         if (a[i] == '(')  
         if (f(&a[i + 1], a[i - 1]) == 0)  
         q(&a[i]);  
         else  
         {  
             while (a[i] != ')')  
             {  
                 i++;  
             }  
         }  
         i++;  
     }  
 }  
 int main()  
 {  
     int l = 0, i = 0;  
     char ch[100];  
     scanf("%s", ch);  
     g(ch);  
     while (ch[i]!='\0')  
     {  
         if (ch[i]!='#')  
         {  
             printf("%c", ch[i]);  
         }  
         i++;  
     }  
     return 0;  
 }  

算法训练 字串逆序

问题描述
  给定一个字符串,将这个串的所有字母逆序后输出。
输入格式
  输入包含一个字符串,长度不超过100,字符串中不含空格。
输出格式
  输出包含一个字符串,为上面字符串的逆序。
样例输入
tsinsen
样例输出
nesnist

 #include<stdio.h>  
 #include<string.h>  
 int main()  
 {  
     char str[100];  
     int len;  
     scanf("%s",str);  
     len=strlen(str)-1;  
     for(;len>=0;len--)  
     printf("%c",str[len]);  
     return 0;  
 }   
 #include <iostream>  
 using namespace std;  
 // 交换两个整数  
 void Swap(int *a, int *b)  
 {  
 int temp=*a;  
     *a=*b;  
     *b=temp;  
 }  
 int main()  
 {  
     int a, b;  
     cin >> a >> b;  
     Swap(&a, &b);  
     cout << a << " " << b;  
     return 0;  
 }  

算法训练 矩阵乘方

问题描述
  给定一个矩阵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为偶数,则A^b%m=(A^(b/2)%m)^2%m,即先把A乘b/2次方对m求余,然后再平方后对m求余。
  若b为奇数,则A^b%m=(A^(b-1)%m)*a%m,即先求A乘b-1次方对m求余,然后再乘A后对m求余。
  这种方法速度较快,请使用这种方法计算A^b%m,其中A是一个2x2的矩阵,m不大于10000。
输入格式
  输入第一行包含两个整数b, m,第二行和第三行每行两个整数,为矩阵A。
输出格式
  输出两行,每行两个整数,表示A^b%m的值。
样例输入
2 2
1 1
0 1
样例输出
1 0
0 1

 #include <stdio.h>  
 int b, m;  
 int a[2][2], ans[2][2], temp[2][2] = {1,1,1,1};  
 void play()  
 {  
     int cnt, cnt2;  
     for(cnt = 0; cnt < 2; ++cnt)  
     {  
         for(cnt2 = 0; cnt2 < 2; ++cnt2)  
         {  
             printf("%d ", ans[cnt][cnt2]);  
         }         
         printf("\n");  
     }     
 }  
 void cp(int arr1[][2], int arr2[][2])  
 {  
     int cnt, cnt2;  
     for(cnt = 0; cnt < 2 ;++cnt)  
         for(cnt2 = 0; cnt2 < 2; ++cnt2)  
             arr1[cnt][cnt2] = arr2[cnt][cnt2];  
 }  
 void mod(int arr[][2])  
 {  
     int cnt, cnt2;  
     for(cnt = 0; cnt < 2; ++cnt)  
         for(cnt2 = 0; cnt2 < 2; ++cnt2)  
             arr[cnt][cnt2] %= m;  
 }  
 void fun2(int a[][2], int b[][2])  
 {  
     int cnt, cnt2;  
     temp[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0];  
     temp[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1];  
     temp[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0];  
     temp[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1];  
 }  
 void fun(int arr[][2], int k)  
 {  
     int cnt;  
     if(k == 0)  
     {  
         mod(temp);  
         cp(ans, temp);  
         return;  
     }  
     if(k == 1)  
     {  
         mod(ans);  
         return;  
     }  
     if(k == 2)  
     {  
         fun2(a, a);  
         cp(ans, temp);  
     //  printf("2\n");  
     //  play();  
         mod(ans);  
         return;  
     }  
     if(k%2 == 0)  
     {  
         fun(arr, k/2);  
         fun2(ans, ans);  
         cp(ans, temp);  
         //printf("=0\n");  
         //play();  
         mod(ans);  
         return;  
     }  
     if(k%2 != 0)  
     {  
         fun(arr, k-1);  
         fun2(ans, arr);  
         cp(ans, temp);  
         //printf("!=0\n");  
     //  play();  
         mod(ans);  
         return;  
     }  
 }  
 int main()  
 {  
     int cnt, cnt2;  
     scanf("%d%d", &b, &m);  
     for(cnt = 0; cnt < 2; ++cnt)  
         for(cnt2 = 0; cnt2 < 2; ++cnt2)  
         {  
             scanf("%d", &a[cnt][cnt2]);  
             ans[cnt][cnt2] = a[cnt][cnt2];  
         }  
     fun(a, b);  
     play();  
     return 0;  
 }  
阅读更多
版权声明:本文为本人辛苦原创文章,如果需要转载,请注明出处,谢谢!!! https://blog.csdn.net/sihai12345/article/details/79238718
所属专栏: 蓝桥杯竞赛训练习题
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭