C程序设计试题(西北工业大学)

Posted on 2019-10-07 10:32  金色的省略号  阅读(1045)  评论(0编辑  收藏  举报

1、取快递

题目内容:

现在网上购物越来越方便了,所以王老师也顺应潮流基本都在网上购买所需物品。但是,网上购物可能需要随时取快递,可王老师要上班显然没办法了。好在她们家楼下有一个便利店可以代收快递,但是需要收取1元/件的服务费。王老师为了少付些服务费,能取得快递还是自己取得,实在不能取才委托便利店代取。王老师能取快递的时间段为8:00~9:00与17:00~21:00(时间段临界点是可以自取的),请帮王老师算算这个月她所需要支付给便利店的快递服务费是多少元。

输入格式:

第一行输入本月的快递数整数n(0~10000),接下来一行输入n个快递送达的时间hh:mm(限定输入的都是合法的时间),每个时间用空格隔开

输出格式:

输出需要支付的快递服务费钱数s

输入样例:

3

12:00 08:40 09:00

输出样例:

1

 1 #include<stdio.h>
 2 int main()
 3 {  
 4     int n,h,m,s=0;
 5     scanf("%d",&n);
 6     
 7     while(n--){
 8         scanf("%2d:%2d",&h,&m);
 9         int x = h*60+m;
10         if(x>=8*60&&x<=9*60||x>=17*60&&x<=21*60);
11         else
12             s++;
13     }
14     printf("%d\n",s);
15     return 0;
16 }

2、神叨的码农

题目内容:

码农Nimo有时编程很不顺利,所以他查阅了一下老黄历,决定与他犯冲的日子不再编程。比如他发现今年跟数字7犯冲,因此他果(yu)断(chun)的决定:凡是今年日期里含有7的日子统统不再编程,比如2016年7月他将休息整个月,当然X月7日、17日、27日也是他的休息日。请你算一下这个码农Nimo某年的休息日有多少天。

输入格式:

输入一个年份值(1900~9999)和码农犯冲的数字(0~9),空格隔开

输出格式:

输出Nimo休息的天数

输入样例:

2016 7

输出样例:

64

 1 #include<stdio.h>
 2 int main()
 3 {  
 4     int year,num,days=0;
 5     int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
 6     scanf("%d%d",&year,&num);
 7     
 8     int leap = year%100==0&&year%4!=0||year%400==0;
 9     if(leap)  month[2] = 29;
10             
11     days += month[num];
12     days += 11*3;
13     if(num==9 && !leap)//如果犯冲数字是9且不是闰年
14         days--;
15     printf("%d\n",days);
16     return 0;
17 }

3、书到底多少页?

豆豆有一本书,书的页码从1开始,豆豆数了数,该书的全部页码中总共出现了N个数字“3”,试编程求这本书至少多少页?

输入格式:

输入整数N(10000>N>0)

输出格式:

输出书的页数

输入样例:

5

输出样例:

31

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

4、句子逆转

题目内容:

输入一个句子,占用一行。句子由单词和单词间的空格组成。单词只有小写字母。单词之间由空格隔开,没有标点符号。单词之间可能有一个或多个空格。每个句子至多有1000个字母。将句子单词的排列顺序倒过来输出。

输入格式:

输入一个字符串

输出格式:

输出逆转的结果(每两个单词间隔一个空格)

输入样例:

it is a test 

输出样例:

test a is it

 1 #include <stdio.h>
 2 #include <string.h>
 3 void print(char *word,int len){
 4     for(int i=len-1; i>=0; --i)
 5         putchar(word[i]);
 6 }
 7 int main()
 8 {  
 9     char word[50] = "";
10     char s[1001] = "";
11     gets(s);
12     int index = 0,flag=0;
13     char *p = s+strlen(s)-1;
14     while(p>=s-1)
15     {
16         if(p>=s && (*p>='a'&&*p<='z'||*p>='A'&&*p<='Z'))
17             word[index++] = *p;
18         else{
19             if(flag)
20                 printf(" ");
21             flag=1;
22             word[index] = '\0';
23             int len = strlen(word);
24             print(word,len);
25             index = 0;
26         }
27         p--;
28     }
29     return 0;
30 }

5、石头剪刀布(并查集,食物链例子)

题目内容:

大家都知道石头、剪刀、布的游戏:石头压过剪刀、剪刀压过布、布压过石头。N个小朋友一起玩石头、剪刀、布游戏。令下后,N个小朋友(编号1~N)一起给出了自己的手势。然后开始讨论游戏的结果,说法有两种:

第一种说法是“1 X Y”,表示X和Y的手势相同。

第二种说法是“2 X Y”,表示X压过Y。

K个小朋友争先恐后的说出了自己的见解,当然他们中有人对游戏规则不是特别熟悉会说错的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

1-当前的话与前面的某些真的话冲突,就是假话;

2-当前的话中X或Y比N大,就是假话;

3-当前的话表示X压过X,就是假话。

你的任务是根据给定的N(1<=N<=50,000)和K句话(0<=K<=10,000),输出假话的总数。

输入格式:

第一行是两个整数N和K,以一个空格分隔。以下K行每行是三个正整数 D、X、Y,两数之间用一个空格隔开,其中D表示说法的种类,X、Y为小朋友的编号。

若D=1,则表示X和Y是手势相同。

若D=2,则表示X压过Y。

输出格式:

只有一个整数,表示假话的数目。

输入样例:

100 7

1 101 1  

2 1 2    

2 2 3    

2 3 3    

1 1 3    

2 3 1    

1 5 5

输出样例:

3

 1 #include<stdio.h>
 2 
 3 typedef struct sth
 4 {
 5     int relation;
 6     long father;
 7 } NODE;
 8 
 9 long n, k;
10 NODE animal[50001];
11 
12 void MakeSet()
13 {
14     int i;
15 
16     for (i = 1; i <= n; i++)
17     {
18         animal[i].relation = 0;
19         animal[i].father = i;
20     }
21 }
22 
23 void Merge (long a, long b, long x, long y, int d)
24 {
25     animal[a].father = b;
26     animal[a].relation = (animal[y].relation - animal[x].relation + 2 + d) % 3;
27 }
28 
29 long Find (long x)
30 {
31     long pre_father;
32 
33     if (x != animal[x].father)
34     {
35         pre_father = animal[x].father;
36         animal[x].father = Find (animal[x].father);
37         animal[x].relation = (animal[x].relation + animal[pre_father].relation) % 3;
38     }
39 
40     return animal[x].father;
41 }
42 
43 int main()
44 {
45     int d;
46     long a, b, x, y, sum = 0;
47 
48     scanf ("%ld %ld", &n, &k);
49 
50     MakeSet();
51 
52     while (k--)
53     {
54         scanf ("%d %ld %ld", &d, &x, &y);
55         if ( (x > n) || (y > n) || ( (x == y) && (d == 2)))
56             sum++;
57         else
58         {
59             a = Find (x);
60             b = Find (y);
61             if ( (a == b) && ( (animal[x].relation - animal[y].relation + 3) % 3 != d - 1))
62                 sum++;
63             else if (a != b)
64                 Merge (a, b, x, y, d);
65         }
66     }
67     printf ("%ld\n", sum);
68     return 0;
69 }

6、上餐策略(贪心算法)

题目内容:

小王经营了一家小吃店,小吃店售卖一种名为“掉渣馅饼”的小吃。由于小王刚开始营业,店的规模和设备数量有限,他每次只能制作一个馅饼,并且制作一个馅饼需要3分钟,但是他的馅饼味道正宗,所以很多顾客愿意等待一会儿来品尝馅饼,生意还不错。有一天,小王刚打开店门(馅饼库存为0),就有M个顾客同时走进来每人点了一个馅饼,M个顾客都有不同的安排使得他们能够等待的时间有限,他们的等待时间分别为Wi (1<=i<=M,Wi为非负整数,单位为分钟)。由于这M个顾客都是老顾客,小王不愿意让顾客心里不舒服,因此他决定如果一个顾客拿到馅饼的时间没有超过他的等待时间则按原价收钱;如果一个顾客拿到馅饼的时间比他能等待的时间晚3分钟以内(包括3分钟)就少收这个顾客1毛钱,晚6分钟以内(含6分钟)就少收2毛钱,晚9分钟以内(含9分钟)就少收3毛钱,收费按此规律递减。请你设计一种服务策略让小王损失最少。 

输入格式:

第一行输入整数M

第二行输入M个非负整数Wi(wi表示编号为i的顾客的等待时间)

输出格式:

输出上餐策略(按照上餐顺序输出顾客的编号,空格隔开。两个顾客顺序任意时按照编号小的顾客在前)

输入样例:

3

7 4 5

输出样例:

2 1 3

 1 /*     
 2     问题分析
 3     1.如果存在,两名(含两名)以上的客人没有超过等待时间,
 4     选择可以等待时间最少的客人(数字最小),赔钱为0;    
 5     2.如果存在,一名(含一名)以下的客人没有超过等待时间,
 6     选择可以等待时间最少的客人(数字最大),最少赔钱为0,依次增加
 7     
 8     输入样例
 9     3
10     7 4 5
11     输出样例
12     2 1 3
13  */
14 #include <stdio.h>
15 #define N 100
16 int main()
17 {   
18     int i, j, n = 3, arr[N] = {7,4,5};
19     int boolean[N] = {0};
20     
21     /* 输入 */
22     scanf("%d",&n);
23     for(i=0; i<n; ++i)
24         scanf("%d",&arr[i]);
25     
26     /* 逐个剔除(用boolean数组) */
27     for(i=0; i<n; ++i)
28     {
29         /* 每次3分钟 */
30         int flag = 0;
31         for(j=0; j<n; ++j){
32             arr[j] -= 3;
33             if(arr[j]>0) flag++;        
34         }
35         /*  最多只有一个正数,取最大*/
36         if(flag<=1)
37         {
38             int max = -1000, maxj;
39             for(j=0; j<n; ++j){
40                 //没剔除的选最大
41                 if(arr[j]>max && !boolean[j])
42                 {
43                     max = arr[j];                    
44                     maxj = j;
45                 }
46             }
47             boolean[maxj] = 1;//剔除
48             printf("%d ",maxj+1);
49         }
50         else{ /* 两个以上正数,取最小 */
51             int min = 1000, minj;
52             for(j=0; j<n; ++j){
53                 //没剔除的选最小
54                 if(arr[j]<min && !boolean[j])
55                 {                    
56                     min = arr[j];
57                     minj = j;
58                 }
59             }
60             boolean[minj] = 1;//剔除
61             printf("%d ",minj+1);
62         }
63     }
64     return 0;
65 }

7、星期信息转换

题目内容:

根据星期数字找出对应星期的英文缩写或输出ERROR。(注:一星期七天的英文缩写为:星期天Sun(对应数字7),星期一Mon,星期二Tues,星期三Wed,星期四Thur,星期五Fri,星期六Sat)

输入格式:

输入整型星期数字

输出格式:

输出对应星期的英文缩写(首字母大写)

输入样例:

4

输出样例:

Thur

 1 #include<stdio.h>
 2 int main()
 3 {
 4     int m;
 5     scanf("%d",&m);    
 6     switch(m){
 7         case 1:printf("Mon");break;
 8         case 2:printf("Tues");break;
 9         case 3:printf("Wed");break;
10         case 4:printf("Thur");break;
11         case 5:printf("Fri");break;
12         case 6:printf("Sat");break;
13         case 7:printf("Sun");break;
14         default:printf("ERROR");break;
15     }    
16     return 0;
17 }

8、等差数列

题目内容:

数列中相邻两项的差相等的数列称为等差数列。现在有一个等差数列,其前三项分别为:1,4,7,请找出一个最小的整数N(数列项的编码从1开始),使得数列的前N项之和大于整数M。

输入格式:

输入M

输出格式:

输出N  

输入样例:

10

输出样例:

3

 

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int m,sum=0;
 6     scanf("%d",&m);
 7     for(int i=1,count=1;sum<m;i+=3,count++)
 8     {
 9         sum+=i;
10         if(sum>m){
11             printf("%d",count);
12             break;
13         }
14     }
15 }

9、竞赛问题

题目内容:

A、B、C、D、E五名学生有可能参加计算机竞赛,根据下列条件判断哪些人参加了竞赛:

(1)A参加时,B也参加;

(2)B和C只有一个人参加;

(3)C和D或者都参加,或者都不参加;

(4)D和E中至少有一个人参加;

(5)如果E参加,那么A和D也都参加。

输入格式:

无输入

输出格式:

输出参加竞赛的人(按照A~E的顺序输出,字母之间用空格隔开)。

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int a,b,c,d,e;
 5       for (a=0; a<=1; a++)
 6           for(b=0; b<=1; b++)
 7               for(c=0; c<=1; c++)
 8                   for(d=0; d<=1; d++)
 9                       for(e=0; e<=1; e++)
10                       {
11                           //1.a参加b也参加:
12                           //a参加b也参加,隐含,或者a不参加b也不参加
13                           //取反:a参加b不参加,或者a不参加b参加
14                           //if(a&&!b||b&&!a)continue;
15                           if(a&&b||!a&&!b);
16                           else continue;
17 
18                           //2.b、c只有一人参加:
19                           //b参加c不参加,或b不参加c参加
20                           //取反:bc都参加,或bc都不参加
21                           //if((b && c) || (!b && !c)) continue;
22                           if(b&&!c||c&&!b);
23                           else continue;
24 
25                           //3.c和d或者都参加,或者都不参加
26                           //逻辑上同1.
27                           //if(( c && !d) || (!c && d)) continue;
28                           if(c&&d||!c&&!d);
29                           else continue;
30 
31                           //4.d和e中至少有一个人参加:
32                           //de都参加,或者d参加e不参加,或者e参加d不参加
33                           //取反:de都不参加
34                           //if (!d && !e) continue;
35                           if(d&&e||d&&!e||!d&&e);
36                           else continue;
37 
38                           //5.如果e参加,那么a和d也都参加:
39                           //ead都参加,或者都不参加,或者e不参加,或者a不参加或者d不参加
40                           //取反:e不参加,ad都参加,或者e参加,或a不参加,或d不参加
41                           //if (!e&&a&&d||e&&(!a||!d)) continue;
42                           if(e&&a&&d||!e&&!a&&!d||!e&&(!a||!d));
43                           else continue;
44     
45                           if(a)printf("A");
46                           if(b)printf("B");
47                           if(c)printf("C ");
48                           if(d)printf("D");
49                           if(e)printf("E");
50                           return 0;
51                       }
52     return 0;
53 }

10、三角形的面积

题目内容:

编写方法计算输入的三个线段a,b,c组成的三角形的面积,不能组成三角形时给出错误提示。

输入格式:

输入a,b,c,均为double型

输出格式:

输出为三角形面积(保留2位小数)或“ERROR”

输入样例:

3 4 5

输出样例:

6.00

 1 #include <stdio.h>
 2 #include <math.h>
 3 int main()
 4 {   
 5     double a,b,c;
 6     scanf("%lf%lf%lf",&a,&b,&c);
 7     if(a+b>c && a+c>b && b+c>a){
 8         double p = (a+b+c)/2;
 9         printf("%.2f",sqrt(p*(p-a)*(p-b)*(p-c)));
10     }
11     else
12         printf("ERROR");    
13     return 0;
14 }

11、查找指定值

题目内容:

从键盘输入N×N个整数存放在N行N列的二维矩形数组A中,查找A数组中包不包括数据x。

输入格式:

第1行输入整型N,第2行给A输入N×N个整型数据,元素之间用空格隔开,第3行输入数据x。

输出格式:

输出A数组是否包括x(包括x输出YES,不包括输出NO)。

输入样例:

3

1 2 3 4 5 6 7 8 9

3

输出样例:

YES

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

12、大数乘幂

题目内容:

在NOJ中曾经出现过大数的加减乘除,这四道题受到了广大师生的好评,虽说是模拟题,但是对大家的代码要求还是极其高的。应广大师生要求,由此将大数运算升级为大数精确乘幂。求R的N次方

输入格式:

输入的数据为实数R和整数N( 0.0 < R < 99.999 )0 < N <= 25,中间用空格隔开。

输出格式:

输出乘幂的值

输入样例:

95.123 12

输出样例:

548815620517731830194541.899025343415715973535967221869852721

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define N 200
 4 int main()
 5 {    
 6     char numStr[10];/* 定义数字字符串 */
 7     /* 定义字符串长度\幂\int数组及下标\int数字\小数点后位数\ */
 8     int i,j,len,n,numArray[N],index,numInt,digit;
 9     memset(numArray, 0, sizeof(numArray));
10     numInt = index = digit = 0;
11     
12     /* 1.输入数字字符串\幂次 */
13     scanf("%s %d",numStr,&n);    
14     len = strlen(numStr);
15     
16     int flag = 1, zero = 0;//判断最后的无效'0',定义标记
17     /* 2.字符串倒序转int数组num */
18     for(i = len-1;i >= 0;i--)
19     {  
20         if(numStr[i] == '0' && flag)
21         {
22             zero++;//无效的'0'
23             continue;
24         }
25         else
26         {
27             flag = 0;
28             if(numStr[i] == '.')
29             {                
30                 digit = len-zero-i-1;//有效的小数点后位数
31                 continue;//去掉小数点
32             }
33         }
34         numArray[index++] = numStr[i] - '0';
35     }
36 
37     /* 3.int数组转int */
38     for(i = index-1;i >= 0;i--)
39         numInt = numInt*10 + numArray[i];
40     
41     /* 4.求幂 */
42     for(i = 1; i < n; i++)//幂次(本身一次)
43     {
44         int carry = 0;    
45         for(j = 0; j < N; j++)//int数字与int数组数字相乘
46         {
47             int tmp = numInt*numArray[j] + carry;
48             numArray[j] = tmp%10;
49             carry = tmp/10;
50         }
51     }
52     
53     /* 5.去掉数组中无效的'0'(小数位控制) */
54     for(i = N-1; numArray[i]==0 && i>n*digit; i--); 
55     
56     /* 6.打印结果 */
57     for(j = i; j >= 0; j--)
58     {
59         if(j == n*digit-1)//小数位之前打印小数点, 无小数位-1
60             printf(".");
61         printf("%d",numArray[j]);
62     }
63     return 0;
64 }