C语言,北京理工大学MOOC 上

1、矩阵的鞍点

 1 #include  <stdio.h>
 2 #define N 32
 3 int main()
 4 {
 5     int m,n;
 6     scanf("%d %d",&m,&n);
 7 
 8     int a[N][N]={0};
 9     for(int i=0;i<m;++i){
10         for(int j=0;j<n;++j){
11             scanf("%d",&a[i][j]);
12         }
13     }
14 
15     int find = 0;
16     for(int i=0;i<m;++i)
17     {
18         //判断行最大值
19         int rowPos=i,columnPos=0,flag = 1;
20         for(int j=1;j<n;++j)
21         {
22             if(a[i][j]>a[rowPos][columnPos]){
23                 rowPos = i;
24                 columnPos = j;
25             }
26         }
27         //判断行最大值,在所在列是否为最小值
28         for(int k=0;k<m;++k){
29             if(a[k][columnPos]<a[rowPos][columnPos]){
30                 flag = 0;
31                 break;
32             }
33         }
34         //行最大值且所在列最小值输出
35         if(flag){
36             printf("Point:a[%d][%d]==%d\n",rowPos,columnPos,a[rowPos][columnPos]);
37             find = 1;
38         }
39     }
40     if(!find){
41         printf("No Point\n");
42     }
43 
44     return 0;
45 }

2、身份证的奥秘

 1 #include <stdio.h>
 2 #include <string.h>
 3 int main()
 4 {    
 5     int weight[17] = {7,9,10,5,8,4,2,1,6,3,
 6         7,9,10,5,8,4,2};
 7     char m[12] = "10X98765432";
 8     
 9     int n;
10     scanf("%d",&n);
11 
12     while(n--)
13     {
14         char buf[20] = "";
15         scanf("%s",buf);
16         int len = strlen(buf);
17 
18         char buf1[20] = "";
19         if(len==15)
20         {
21             strncpy(buf1,buf,6);
22             if(strstr(&buf[12],"996")||strstr(&buf[12],"997")||
23                     strstr(&buf[12],"998")||strstr(&buf[12],"999")){
24                 strcat(buf1,"18");
25             }
26             else
27                 strcat(buf1,"19");
28             strcat(buf1,&buf[6]);
29             strcpy(buf,buf1);
30         }
31 
32         int sum = 0;
33         for(int i=0; i<17; ++i)
34             sum += (buf[i]-'0')*weight[i];
35 
36         if(len==15){
37             buf[17] = m[sum%11];
38             printf("%s\n",buf);
39         }
40         else if(len==18 && m[sum%11]==buf[17])
41             printf("Valid\n");
42         else
43             printf("Invalid\n");
44     }
45     return 0;
46 }

3、安全的密码

 1 #include <stdio.h>
 2 #include <string.h>
 3 int main()
 4 {
 5     int n;
 6     scanf("%d",&n);
 7     getchar();
 8     while(n--)
 9     {
10         char str[20] = "";
11         gets(str);
12 
13         int a[4] = {0};
14         int count = 0;
15         int len = strlen(str);
16         for(int i=0; i<len; ++i)
17         {
18             if(str[i]>='A'&&str[i]<='Z'){
19                 a[0]++;
20                 if(a[0]==1)
21                     count++;
22             }
23             else if(str[i]>='a'&&str[i]<='z'){
24                 a[1]++;
25                 if(a[1]==1)
26                     count++;
27             }
28             else if(str[i]>='0'&&str[i]<='9'){
29                 a[2]++;
30                 if(a[2]==1)
31                     count++;
32             }
33             else {
34                 a[3]++;
35                 if(a[3]==1)
36                     count++;
37             }
38         }
39 
40        if(len<6||count==1)
41             puts("Not Safe");
42         else if(count==2)
43             puts("Medium Safe");
44         else
45             puts("Safe");
46     }
47     return 0;
48 }

4、单词排序

 1 #include <stdio.h>
 2 #include <string.h>
 3 int main()
 4 {
 5     char a[5][80],temp[80]="";
 6     int n=5, t, i=0;
 7     t = n;
 8     while(t--){
 9         scanf("%s",a[i]);
10         for(int j=0; j<i; ++j){
11             if(strcmp(a[i],a[j])>0){
12                 strcpy(temp,a[i]);
13                 strcpy(a[i],a[j]);
14                 strcpy(a[j],temp);
15             }
16         }
17         i++;
18     }
19 
20     t = n, i=0;
21     while(t--)
22         printf("%s\n",a[i++]);
23 
24     return 0;
25 }

5、回文数

题目内容:

输出所有不超过n(取n<256)的、其平方具有对称性质的正整数(也称为回文数)。

如: 1*1=1; 2*2=4;3*3=9;11*11=121;1,2,3,11是回文数。

输入格式:

输入n(n<256)

输出格式:

输出所有不超过n的回文数

输入样例:

3

输出样例:

1[回车]

2[回车]

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int m;
 5     scanf("%d",&m);
 6 
 7     for(int i=1; i<m; ++i)
 8     {
 9         int n = i*i, num = 0;
10         while(n){
11             num = num*10 + n%10;
12             n /= 10;
13         }
14         if(num==i*i)
15             printf("%d\n",i);
16     }
17 
18     return 0;
19 }

6、组成最大数

题目内容:

任意输入一个自然数,输出该自然数的各位数字组成的最大数。

输入格式:

自然数 n

输出格式:

各位数字组成的最大数

输入样例:

1593

输出样例:

9531[回车]

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int arr[10] = {0};
 6     int n;
 7     scanf("%d",&n);
 8     while(n)
 9     {
10         arr[n%10]++;
11         n /= 10;
12     }
13     for(int i=9; i>=0; --i)
14         while(arr[i]--)
15             printf("%d",i);
16     printf("\n");
17     return 0;
18 }

7、手工计算器

题目内容:

大名鼎鼎的帕斯卡(物理学家,发现大气压的那个)的老爸是一个税务官,每天晚上都要把白天记下的账目进行一系列计算,因此需要大量的计算工作,帕斯卡为了减轻父亲每日的劳顿,发明了手摇计算器。

我们现在也来实现一个计算器:

输入一系列的数值和符号,请你输出计算结果【只考虑加减】。

输入若干行,直到出现“=”,就可以输出结果了

输入格式:

5.0+

3.0+

6.0+

8.0-

9.0+

2.0=

输出格式:

15.00(保留2位小数)【回车】

输入样例:

4.0+

3.0-

2.0+

1.0=

输出样例:

6.00

 1 #include <stdio.h> 
 2 #include <stdlib.h>   
 3 #include <string.h>
 4 
 5 int main()
 6 {
 7     double sum = 0;
 8     char s[100] = "";
 9     char ch;
10     scanf("%s",s);
11     sum += atof(s);
12     do{        
13         ch = s[strlen(s)-1];
14         switch(ch)
15         {
16             case '+':
17                 scanf("%s",s);
18                 sum += atof(s);
19                 break;
20             case '-':
21                 scanf("%s",s);
22                 sum -= atof(s);
23                 break;
24         }        
25     }while(ch!='=');
26     printf("%.2f\n",sum);    
27     return 0;
28 }

8、三天打鱼两天晒网

题目内容:

元旦,新年伊始,小明又立志了,作为一个海南省的资深渔民,他计划从元旦那天开始,两天晒网,三天打鱼。

假定1月1日开始执行计划,那么1月1日和1月2日是晒网的日子,1月3日,4日,5日是打鱼的日子。请你计算一下,给定的日期,他应该是打鱼还是晒网?【计划从每年的1月1日开始执行】

输入格式:

2019,5,8

输出格式:

打鱼:fishing(回车)

晒网:sunning net(回车)

输入样例:

2019,5,8

输出样例:

fishing

 1 #include<stdio.h>
 2 int inputdate();
 3 int main()
 4 {
 5     int n = inputdate();
 6    /*  if(-1==n){
 7         printf("Invalid input");
 8     }
 9     else  */
10     if(n%5==0||n%5==4){
11         printf("sunning net\n");
12     }
13     else{
14         printf("fishing\n");
15     }
16  
17     return 0;
18 }
19 int inputdate()
20 {
21     int year,month,day;
22     int n = scanf("%d,%d,%d",&year,&month,&day);
23     /* if(3 != n||year<1990||month>12||month<=0||day>31||day<=0){
24         return -1;
25     } */
26  
27     int date[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},
28                      {31,29,31,30,31,30,31,31,30,31,30,31}};
29  
30     int sum = 0, flag =(year%4==0&&year%100!=0)||(year%400==0);
31     for(int i=0;i<month-1;++i){
32         sum +=date[flag][i];
33     }
34  
35     return sum+day;
36 }

9、照相

题目内容:

有n个同学(偶数个)和老师一起照毕业照,老师必须站在最中间,同学们分成两组,分列老师左右两边。

假设有A、B、C、D四个人。假设分好组,AB一组,CD一组。一共有8种不同的站位。

现假设组已经分好,那么一共有多少种不同的站法,需要照多少张照片?

输入格式:

4

输出格式:

8【回车】

输入样例:

4

输出样例:

8

 1 /*
 2     n个同学分成2组,每组n/2排列(阶乘)
 3     {(n/2)!*(n/2)!}*2
 4  */
 5 #include<stdio.h>
 6 int fac(int n);
 7 int main()
 8 {
 9     int n;
10     scanf("%d",&n);    
11     printf("%d\n",(fac(n/2)*fac(n/2)*2));
12     return 0;
13 }
14 int fac(int n)
15 {
16     if(n==1)
17         return 1;
18     return n*fac(n-1);
19 }

10、字符串走马灯

题目内容:

多彩的霓虹灯点缀了我们的夜生活,很多店铺都用各式各样的霓虹灯来招徕顾客。

你是一家新店的店主,决定采用霓虹灯和传统走马灯结合的方式来展现商品信息。

走马灯的规则如下:

对于给定的字符串abc(不超过20),走马灯应该连续出现:

abc

bca

cab

abc

如此循环往复(第一行出现的字符串和最后一行的字符都和输入一模一样)

输入格式:

一个字符串,如abc

输出格式:

abc

bca

cab

abc

输入样例:

abc

输出样例:

abc

bca

cab

abc

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #define N 256
 5 int main( )
 6 {    
 7     char s[N] = "";    
 8     char *p = s;
 9     gets(s);
10     /* 打印次数, 字符串长度, 输出的开始位置 */
11     int n,t1,t2,i=0;
12     n = strlen(s)+1;
13     t1 = t2 = strlen(s);
14     
15     if(1==strlen(s))/*只一个字符打印一次*/
16         puts(s);
17     else
18         while(n--)/*打印字符串的个数+1次*/
19         {
20             t1 = t2;
21             p = s+i;/*打印开始位置*/
22             while(t1--){
23                 if(*p=='\0')
24                     p = s;
25                 putchar(*p++);                
26             }
27             putchar('\n');
28             i++;
29         }    
30     return 0;
31 }

11、质数组成的整数

题目内容:

输入一个N位数,N大于等于2且小于8.

考察每一组两位数,判断每一组两位数都是质数的,请输出YES,否则输出NO。

例如:

“537”中有53,37两组两位数,都是质数,所以输出YES.

“4236”中有42,23,36三组两位数,且不都是质数,因此输出NO.

输入格式:

537

输出格式:

YES

输入样例:

537

输出样例:

YES

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <math.h>
 5 int isPrime(int n){
 6     for(int i=2; i<sqrt(n); ++i)
 7         if(n%i==0)
 8             return 0;
 9     return 1;
10 }
11 int main( )
12 {    
13     int N;
14     int flag = 1;
15     scanf("%d",&N);
16     while(N)
17     {
18         if(!isPrime(N%100)){
19             flag = 0;
20             break;
21         }
22         if(N>=100){
23             N/=10;    
24         }
25         else
26             break;            
27     }
28     if(flag)
29         printf("YES");
30     else
31         printf("NO");
32     return 0;
33 }

12、重复字符计算

题目内容:

总有些字符串中,存在一些重复出现的字符,请将每一个字符串中重复出现的最后一个字符替换成相应的重复数。

例如,在aaa字符串中,a重复了3次,那么就将最后一个a替换为3,即aa3

只出现1次的,当然就不用处理了,因为没有出现重复次数嘛

我们这里的字符串,在变换后长度也不会超过100的

输入格式:

aaa

输出格式:

aa3

输入样例:

abc

输出样例:

abc

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #define N 256
 5 
 6 char s[N] = "";/*全局变量*/
 7 void fun(char *p,char ch, int count)
 8 {    /*1.保存最后一个字符后的字符串  */        
 9     while(*p!=ch)
10         p--;
11     char *t = p+1;
12     /*2.最后之前的字符串  */
13     *p = '\0';
14     /* 重复字符个数+之后的字符串 */
15     char s1[N] = "";
16     sprintf(s1,"%d",count);
17     strcat(s1,t);
18     /* 之前的字符串+重复字符个数+之后的字符串 */
19     strcat(s,s1);
20 }
21 int main( )
22 {    /*输入计算重复字符  */    
23     scanf("%s",s);
24     int key[N] = {0};
25     for(int j=0; s[j]; ++j)
26         key[s[j]]++;
27     /* 字符串结束标记之前的位置 */
28     char *p = s+strlen(s)-1;
29     /*i为字符, 修改字符串*/
30     for(int i=0; i<N; ++i){        
31         if(key[i]>1){
32             p = s+strlen(s)-1;/* 字符串结束标记之前的位置 */
33             fun(p,i,key[i]);/*修改字符串*/
34         }
35     }
36     printf("%s",s);/*打印修改字符串*/
37     return 0;
38 }

13、蛇形矩阵

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 int main( )
 6 {    
 7     int a[10][10],s=0,n,i=1,j=1,t=0;
 8     scanf("%d",&n);
 9     /* 输入蛇形矩阵 */
10     while (i<n||j<n)
11     {
12         ++s;
13         a[i-1][j-1]=s; //
14         if(t)//
15         {
16             if (j==1)
17             {
18                 t=0;
19                 if (n==i) 
20                     ++j; 
21                 else 
22                     ++i;
23             }
24             else if(n==i)
25             {
26                 t=0;
27                 ++j;
28             }
29             else
30             {
31                 ++i;--j;
32             }
33         }            
34         else if (i==1)//
35         {
36             t=1;
37             if (n==j) 
38                 ++i;
39             else 
40                 ++j;
41         }
42         else if (n==j)
43         {
44             t=1;
45             ++i;
46         }
47         else
48         {
49             --i;
50             ++j;
51         }
52     }
53     
54     a[n-1][n-1]=s+1;
55     
56     /* 输出矩阵 */
57     if (n>1)
58     {
59         for(i=1;i<=n;i++)
60         {
61             printf("%2d",a[i-1][0]);
62             for(j=2;j<=n;j++)
63                 printf("%3d",a[i-1][j-1]);
64             printf("\n");
65         }
66     }    
67     else
68     {
69         printf("1\n");
70     }            
71     return 0;
72 }

14、洗牌

题目内容:

假设我们有 2n 张牌,它们以 1, 2, ..., n, n+1, ..., 2n 编号并在开始时保持着这种顺序。一次洗牌就是将牌原来的次序变为 n+1, 1, n+2, 2, ..., 2n, n,也就是将原来的前 n 张牌放到位置 2, 4, ..., 2n,并且将余下的 n 张牌按照他们原来的次序放到奇数位置 1, 3, ..., 2n-1。已经证明对于任何一个自然数 n,这 2n 张牌经过一定次数的洗牌就回到原来的次序。但我们不知道对于一个特定的 n,需要几次洗牌才能将牌洗回原来的次序。

输入格式:

牌张数的一半n,即初始情况下一共有2n张牌,n为int型整数

输出格式:

将牌洗回原来的次序所需要的洗牌次数

输入样例:

10

输出样例:

6[回车]

 1 #include <stdio.h>
 2 #define N 100000
 3 int main()
 4 {
 5     int n;
 6     scanf("%d",&n);
 7     int a[N] = {0};
 8     int b[N] = {0};
 9     for(int i=0; i<2*n; ++i)
10         b[i] = i+1;
11 
12     int count=0,flag=0;
13     while(flag<2*n){
14         count++;
15         flag = 0;
16         int j = 0, t = n;
17         for(int i=0; i<2*n; ++i){
18             if(i%2)
19                 a[i] = b[j++];
20             else
21                 a[i] = b[t++];
22         }
23         for(int i=0; i<2*n; ++i){
24             b[i] = a[i];
25             if(a[i]==i+1)
26                 flag++;
27         }
28     }
29     printf("%d\n",count);
30     return 0;
31 }

15、邮票组合

题目内容:

我们寄信都要贴邮票,在邮局有一些小面值的邮票,通过这些小面值邮票中的一张或几张的组合,可以满足不同邮件的不同的邮资。

现在,邮局有4种不同面值的邮票。在每个信封上最多能贴5张邮票,面值可相同,可不同。

输入格式:

四种邮票的面值。

输出格式:

用这四种面值组成的邮资最大的从1开始的一个连续的区间。

说明:

如结果为10,则表明使用4张邮票可组合出1、2、3、4、5、6、7、8、9、10这些邮资。

名词解释:

邮资:就是你寄东西需要花多少钱。

邮票面额:是由国家发行的具有固定价格的花纸片,被称为邮票。

如果你寄东西,邮局称了重量,告诉你要240分。这样你就要贴邮票了。如果现在邮局的邮票有面值为80分、50分、20分和10分的四种,你就可以 采用不同的组合得到240的邮资,例如:采用3张80分的可以凑出240分;或者24张10分的凑起来240分也可以。显然不同邮票的组合都可以得到同样一种邮资。

输入样例:

1 4 12 21

输出样例:

The max is 71.
 1 #include<stdio.h>
 2 int f(int *m,int a1,int a2,int a3,int a4)
 3 {
 4     int i,j,k,p;
 5     for( i = 0 ; i <= 5 ; i++ )
 6     { 
 7         for( j = 0 ; j <= 5 - i ; j++ ) 
 8         { 
 9             for( k = 0 ; k <= 5 - i - j ; k++ ) 
10             { 
11                 for( p = 0 ; p <= 5 - i - j - k ; p++ ) 
12                 {
13                     if( a1 * i + a2 * j + a3 * k + a4 * p == *m)
14                         return 1;              
15                 }            
16             } 
17         } 
18     } 
19     return 0;    
20 }
21 int main()
22 {
23     int a1, a2, a3, a4, m=1;
24     scanf("%d%d%d%d",&a1,&a2,&a3,&a4);
25     while(f(&m,a1,a2,a3,a4))
26         m++; 
27     printf("The max is %d.\n",--m);
28     return 0;
29 }

16、火锅火锅和火锅

题目内容:

众所周知,沫沫以火锅为生。在E8的聚餐活动中,他经常卖萌卖无辜领着大家吃火锅。。

有一天,沫沫听说学校附近的哺呷哺呷在某现充的赞助下有一个优惠活动,只需30软妹币,对每个客人,它会上N道菜,但是客人只能挑选其中连续上的一些菜。

于是他非常兴奋的拉着灰灰和渣渣去吃火锅去啦。

沫沫是一个十分挑食的人,所以他对每一道菜都有一个愉快度(当然因为他的挑食,某些事物的愉快度会是负数)。

为了让沫沫能非常愉快的享受这次聚餐,善解人意的灰灰和渣渣决定帮他计算,他们应该怎么选择菜才能使沫沫最开心地吃完这次聚餐。

输入格式:

第一行是一个整数T,(T <= 10)表示测试案例的个数

对于每个测试案例,第一行是一个整数N,( 1<=N <= 10000)表示菜的个数

接下来的N个数字,第i个数字si表示沫沫对第i道菜的愉快度。( -1000 <=si <= 1000)

PS:由于CF又被血虐掉rating,所以沫沫的起始愉快度是0

PPS:沫沫完全可能得到一个为负值的愉快值, poor 沫沫。。

输出格式:

对于每个样例,输出一个数字,表示沫沫吃完之后愉快度的最大值。

HINT:

对于 5

6 -1 5 4 -7

我们选择6, -1, 5, 4这四道菜(注意必须是连续的,所以不能跳过-1)

做完后请思考,如果N的范围是1<=N<=100000呢?

输入样例:

2
5
6 -1 5 4 -7
7
0 6 -1 1 -6 7 -5

输出样例:

14
7
 1 #include<stdio.h>
 2 int main()
 3 {
 4     /**<1.案例个数*/
 5     int n;
 6     scanf("%d",&n);
 7     while(n--)
 8     {
 9         /**<2.菜的个数*/
10         int m,sum = 0,max = -1000;
11         scanf("%d",&m);
12         while(m--)
13         {
14             int x;
15             scanf("%d",&x);
16             sum += x;
17             if(sum>max)/**<愉快度x的最大值也可能是负值*/
18                 max = sum;
19             /**< 为了sum最大,一旦发现sum小于0赋值为0*/
20             else if(sum<0)
21                 sum = 0;
22         }
23         printf("%d\n",max);
24     }
25     return 0;
26 }

17、子数整除

题目内容:

对于一个五位数a1a2a3a4a5,可将其拆分为三个子数:

  • sub1=a1a2a3

  • sub2=a2a3a4

  • sub3=a3a4a5

例如,五位数20207可以拆分成:

  • sub1=202

  • sub2=020(=20)

  • sub3=207

现在给定一个正整数K,要求你编程求出10000到30000之间所有满足下述条件的五位数,条件是这些五位数的三个子数sub1、sub2、sub3都可被K整除。

输出时请按照由小到大的顺序排列(每行输出一个数)。

输入格式:

一个正整数K

输出格式:

请按照由小到大的顺序排列(每行输出一个数)

输入样例:

15

输出样例:

22555[回车]

25555[回车]

28555[回车]

30000[回车]

 1 #include<stdio.h>
 2 int  main( )
 3 { 
 4     int k;
 5     scanf("%d",&k);
 6     for(int i=10000; i<=30000;++i)
 7     {
 8         int sub1 = i/100;
 9         int sub2 = i/10%1000;
10         int sub3 = i%1000;
11         
12         if(sub1%k==0&&sub2%k==0&&sub3%k==0)
13             printf("%d\n",i);
14     }    
15     return 0; 
16 }