C语言测试题

来源:互联网 发布:怎么提升淘宝点击率 编辑:程序博客网 时间:2024/04/29 07:55

Problem A: 位操作

Description

假设你工作在一个32位的机器上,你需要将某一个外设寄存器的第X位设置成0(最低位为第0位,最高位为第31位),将第Y位开始的连续三位设置成110(从高位到低位的顺序),而其他位保持不变。对给定的寄存器值R,及X,Y,编程计算更改后的寄存器值R。

Input

仅一行,包括R,X,Y,以逗号","分隔,R为16进制表示的32位整数,X,Y在0-31之间且Y>=3,(Y-X)的绝对值>=3,保证两次置位不会重合

Output

更改后的寄存器值R(16进制输出)

Sample Input

12345678,0,3

Sample Output

1234567c

解题思路:

很简单的位操作,但是需要注意的是Y那里是 110,不能直接或上110,而是先两次SET,在CLR。dave就在这里浪费了有1个小时,惭愧

code

Code:
  1. #include <stdio.h>  
  2.   
  3. #define CLR(r, x)   r &= ~(1UL << x)  
  4. #define SET(r, y)   r |=  (1UL << y)  
  5.   
  6. int main()  
  7. {  
  8.     int r, x, y;  
  9.     scanf("%x,%d,%d", &r, &x, &y);  
  10.   
  11.     CLR(r,x);  
  12.     SET(r,y);  
  13.     SET(r,y-1);  
  14.     CLR(r,y-2);  
  15.   
  16.     printf("%x", r);  
  17.     return 0;  
  18. }  

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————— Problem B: 破译密码

Description

据说最早的密码来自于罗马的凯撒大帝。消息加密的办法是:对消息原文中的每个字母,分别用该字母之后的第5个字母替换(例如:消息原文中的每个字母A都分别替换成字母F)。而你要获得消息原文,也就是要将这个过程反过来。

密码字母:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z M
原文字母:V W X Y Z A B C D E F G H I J K L M N O P Q R S T U

注意:只有字母会发生替换,其他非字母的字符不变,并且消息原文的所有字母都是大写的。

Input

最多不超过100个数据集组成,每个数据集之间不会有空行,每个数据集由3部分组成:

  1. 起始行:START
  2. 密码消息:由1到200个字符组成一行,表示凯撒发出的一条消息.
  3. 结束行:END


在最后一个数据集之后,是另一行:ENDOFINPUT

Output

每个数据集对应一行,是凯撒的原始消息。

Sample Input

START

NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX

END

START

N BTZQI WFYMJW GJ KNWXY NS F QNYYQJ NGJWNFS ANQQFLJ YMFS XJHTSI NS WTRJ

END

START

IFSLJW PSTBX KZQQ BJQQ YMFY HFJXFW NX RTWJ IFSLJWTZX YMFS MJ

END

ENDOFINPUT

Sample Output

IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES

I WOULD RATHER BE FIRST IN A LITTLE IBERIAN VILLAGE THAN SECOND IN ROME

DANGER KNOWS FULL WELL THAT CAESAR IS MORE DANGEROUS THAN HE

 

解题思路

凯撒编码,判断字符是否是字母,并循环-5即可,记得要循环哦,非常简单的题目哦

code

Code:
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <ctype.h>  
  4. #define N 202  
  5.   
  6. char str[N]={0};
  7.   
  8. int main()  
  9. {  
  10.     char *p;  
  11.   
  12.     gets(str);  
  13.     while( strcmp(str, "ENDOFINPUT") != 0 )  
  14.     {
  15.         if ( (strcmp(str, "START") !=0)  
  16.             &&(strcmp(str, "END") != 0) )  
  17.         {
  18.             for(p=str; *p !='/0'; p++)  
  19.             {  
  20.                 if( isupper(*p) )  
  21.                     *p += *p-5 <'A' ? 26-5: -5;  
  22.             }  
  23.             puts(str);  
  24.         }  
  25.         gets(str);  
  26.     }
  27.     return 0;  

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

Problem C: 小孩报数问题

Description

有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。

Input

第一行输入小孩的人数N(N<=64)
接下来每行输入一个小孩的名字(人名不超过15个字符)
最后一行输入W,S (W < N),用逗号","间隔

Output

按人名输出小孩按顺序出列的顺序,每行输出一个人名

Sample Input

5

 

Xiaoming

 

Xiaohua

 

Xiaowang

 

Zhangsan

 

Lisi

 

2,3

Sample Output

Zhangsan

 

Xiaohua

 

Xiaoming

 

Xiaowang

 

Lisi

 

解题思路

 

约瑟夫环的问题,简单题目,但是dave一开始把题目看的不细心,以为是倒序输出,就花了很长时间用链表解决,结果超时(就算不超时也肯定错误),后来一看原来是正序,又用数组重写。 需要注意的就是第一次数人从当前s点就算第一个,以后数人下个人才算第一个,用一点点小技巧把第一数人的起始点向前退1个就ok了。这里也浪费了1个小时

 

 code

Code:
  1. #include <stdio.h>  
  2.   
  3. #define PEOPLE_NUM  65  
  4. #define NAME_LEN    16  
  5.   
  6. struct people  
  7. {  
  8.     char name[NAME_LEN];  
  9.     char flag;  
  10. };  
  11. void input();  
  12. void calc();  
  13.   
  14. struct people children[PEOPLE_NUM];  
  15.   
  16. int n,w,s;  
  17.   
  18. int main()  
  19. {  
  20.     input();  
  21.     calc();  
  22.   
  23.     return 0;  
  24. }  
  25.   
  26. void input()  
  27. {  
  28.     int i;  
  29.   
  30.     scanf("%d/n", &n);  
  31.     for(i=1; i<=n ;i++)  
  32.     {  
  33.         gets(children[i].name);  
  34.         children[i].flag=0;  
  35.     }  
  36.     scanf("%d,%d", &w, &s);  
  37. }  
  38.   
  39. void calc()
  40. {
  41.     int i ,out ,pos ;  
  42.     for(out=0,pos=w-1; out<n ; out++)  
  43.     {  
  44.             for(i=0; i<s;)  
  45.             {  
  46.                 pos= (pos == n ? 1:pos+1);  
  47.   
  48.                 if(children[pos].flag == 0)  
  49.                     i++;  
  50.   
  51.             }  
  52.             puts(children[pos].name);  
  53.             children[pos].flag = 1;  
  54.     }  
  55. }  

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

Problem D: 时间日期格式转换

Description

世 界各地有多种格式来表示日期和时间。对于日期的常用格式,在中国常采用格式的是“年年年年/月月/日日”或写为英语缩略表示的”yyyy/mm/dd”, 此次编程大赛的启动日期“2009/11/07”就是符合这种格式的一个日期,而北美所用的日期格式则为“月月/日日/年年年年”或”mm/dd /yyyy”,如将“2009/11/07”改成这种格式,对应的则是”11/07/2009”。对于时间的格式,则常有12小时制和24小时制的表示方 法,24小时制用0-24来表示一天中的24小时,而12小时制只采用1-12表示小时,再加上am/pm来表示上午或下午,比如”17:30:00”是 采用24小时制来表示时间,而对应的12小时制的表示方法是”05:30:00pm”。注意12:00:00pm表示中午12点,而12:00:00am 表示凌晨12点。

对于给定的采用”yyyy/mm/dd”加24小时制(用短横线”-”连接)来表示日期和时间的字符串,请编程实现将其转换成”mm/dd/yyyy”加12小时制格式的字符串。

Input

第一行为一个整数T(T<=10),代表总共需要转换的时间日期字符串的数目。
接下来的总共T行,每行都是一个需要转换的时间日期字符串。

Output

分行输出转换之后的结果

Sample Input

2 2009/11/07-12:12:12

 

1970/01/01-00:01:01

Sample Output

11/07/2009-12:12:12pm

 

01/01/1970-12:01:01am

Hint

注意中午和凌晨时间的特殊表示

解题思路

算法简单但是功能稍微复杂的题目。

日期的变更可以利用向量循环移位的思路来解决,但是稍稍不同,因为yyyy/mm/dd循 环移位只能变成mm/ddyyyy/,所以要变通下。先y1y2y3y4翻转变成y4y3y2y1,在m1m2/d1d2翻转变成d2d1/m2m1,然 后整体y4y3y2y1/d2d1/m2m1翻转变成m1/m2/d1/2/y1/y2/y3/y4 解决。

日期的变更就只能用if语句按照小时来判断了,注意12小时制没有0点,最少1点,最多12点。我就是这个没有理解WA了两次,后来用手机测试了下,理解了变换步骤,终于解决。注意24小时制中的0点xx和12点xx变换都为12点am/pm.

code

Code:
  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. #define T   10  
  5. #define DATE_LEN 10  
  6. #define TIME_LEN 10  
  7. #define SUM_LEN  22  
  8.   
  9. static void reverse(char a[], int n);  
  10. void change_date(char date[]);  
  11. void change_time(char time[]);  
  12.   
  13. int t;  
  14. char datetime[T][SUM_LEN];  
  15.   
  16. int main()  
  17. {  
  18.     int i;  
  19.   
  20.     scanf("%d/n", &t);  
  21.     //scanf  
  22.     for(i=0; i<t; i++)  
  23.     {  
  24.         gets(datetime[i]);  
  25.     }  
  26.     //change date & time  
  27.     for(i=0; i<t; i++)  
  28.     {  
  29.         //date  
  30.         change_date(datetime[i]);  
  31.         //time  
  32.         change_time(datetime[i]+DATE_LEN+1);  
  33.     }  
  34.     //output  
  35.     for(i=0; i<t; i++)  
  36.     {  
  37.         puts(datetime[i]);  
  38.     }  
  39.     return 0;  
  40. }  
  41. static void reverse(char a[], int n)  
  42. {  
  43.     int i;  
  44.     char t;  
  45.     for(i=0,n--; i<n-i; i++)  
  46.     {  
  47.         t = a[i];  
  48.         a[i] = a[n-i];  
  49.         a[n-i] = t;  
  50.     }  
  51. }  
  52. void change_date(char date[])  
  53. {  
  54.     reverse(date, 4);  
  55.     reverse(date+5, 5);  
  56.     reverse(date, DATE_LEN);  
  57. }  
  58. void change_time(char time[])  
  59. {  
  60.     if ( (time[0]>='1') && (time[1]>='2') )  
  61.     {  
  62.   
  63.         if( (time[0]!='1') || (time[1]!='2')  )  
  64.         {  
  65.             time[0] -= 1;  
  66.             time[1] -= 2;  
  67.         }  
  68.         strcat(time, "pm");  
  69.     }  
  70.     else  
  71.     {  
  72.         if( (time[0]=='0') && (time[1]=='0')  )  
  73.         {  
  74.             time[0] += 1;  
  75.             time[1] += 2;  
  76.         }  
  77.         strcat(time, "am");  
  78.     }  
  79. }  

 

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

Problem E: 字母旋转游戏

Description

给定两个整数M,N,生成一个M*N的矩阵,矩阵中元素取值为A至Z的26个字母中的一个,A在左上角,其余各数按顺时针方向旋转前进,依次递增放置,当超过26时又从A开始填充。例如,当M=5,N=8时,矩阵中的内容如下: A B C D E F G H V W X Y Z A B I U J K L M N C J T I H G F E D K S R Q P O N M L

Input

M为行数,N为列数,其中M,N都为大于0的整数。

Output

分行输出相应的结果

Sample Input

4 9

Sample Output

A B C D E F G H I

 

V W X Y Z A B C J

 

U J I H G F E D K

 

T S R Q P O N M L

解题思路

稍微有点难度的题目,最重要的是矩阵四个边的边界值以及填充完成条件。在我的代码里,设置了四个变量u,d,l,r,分别代表上下左右的边界[u,d),[l,r),如果有两个边界重合就说明已经填充完毕了。当然你也可以用填充计数器来判断,如果等于行*列数,也是填满了。建立正确而又简洁的模型很重要。

code

Code:
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. void calc(char *ma, int m, int n);  
  5. void output(char *ma, int m, int n);  
  6.   
  7. int main()  
  8. {  
  9.     int m=4, n=9;  
  10.     char *matrix;  
  11.   
  12.     scanf("%d %d", &m, &n);  
  13.     matrix = malloc(m*n*sizeof(char));  
  14.     if (matrix == NULL)  
  15.         return -1;  
  16.     calc(matrix, m, n);  
  17.     output(matrix, m, n);  
  18.     return 0;  
  19. }  
  20. void output(char *ma, int m, int n)  
  21. {  
  22.     int i,j;  
  23.     for(i=0; i<m; i++)  
  24.     {  
  25.         for(j=0; j<n; j++)  
  26.         {  
  27.             printf("%4c", ma[n*i+j]);  
  28.         }  
  29.         puts("");  
  30.     }  
  31. }  
  32.   
  33. void calc(char *ma, int m, int n)  
  34. {  
  35.     int i=0, j=-1;  
  36.     int u,d,l,r,sum;  
  37.   
  38.     sum=0;  
  39.     u=0;  
  40.     d=m;  
  41.     l=0;  
  42.     r=n;  
  43.     while(1)  
  44.     {  
  45.         if (l==r)  
  46.             break;  
  47.         for(j++; j<r; j++)  
  48.         {  
  49.             ma[n*i+j] = (sum++)%26 +'A';  
  50.         }  
  51.         u++;  
  52.         j--;  
  53.   
  54.         if (u==d)  
  55.             break;  
  56.         for(i++; i<d; i++)  
  57.         {  
  58.             ma[n*i+j] = (sum++)%26 +'A';  
  59.         }  
  60.         r--;  
  61.         i--;  
  62.   
  63.   
  64.         if (l==r)  
  65.             break;  
  66.         for(j--; j>=l; j--)  
  67.         {  
  68.             ma[n*i+j] = (sum++)%26 +'A';  
  69.         }  
  70.         d--;  
  71.         j++;  
  72.   
  73.         if (u==d)  
  74.             break;  
  75.         for(i--; i>=u; i--)  
  76.         {  
  77.             ma[n*i+j] = (sum++)%26 +'A';  
  78.         }  
  79.         l++;  
  80.         i++;  
  81.     }  
  82. }  
原创粉丝点击