Problem A: 位操作
Description
Input
Output
Sample Input
12345678,0,3
Sample Output
1234567c
解题思路:
很简单的位操作,但是需要注意的是Y那里是 110,不能直接或上110,而是先两次SET,在CLR。dave就在这里浪费了有1个小时,惭愧
code
- #include <stdio.h>
- #define CLR(r, x) r &= ~(1UL << x)
- #define SET(r, y) r |= (1UL << y)
- int main()
- {
- int r, x, y;
- scanf("%x,%d,%d", &r, &x, &y);
- CLR(r,x);
- SET(r,y);
- SET(r,y-1);
- CLR(r,y-2);
- printf("%x", r);
- return 0;
- }
———————————————————————————————————————————————————————————————————————————————————————————————————————————————————— Problem B: 破译密码
Description
密码字母: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
- 起始行:START
- 密码消息:由1到200个字符组成一行,表示凯撒发出的一条消息.
- 结束行: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
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #define N 202
- char str[N]={0};
- int main()
- {
- char *p;
-
- gets(str);
- while( strcmp(str, "ENDOFINPUT") != 0 )
- {
- if ( (strcmp(str, "START") !=0)
- &&(strcmp(str, "END") != 0) )
- {
- for(p=str; *p !='/0'; p++)
- {
- if( isupper(*p) )
- *p += *p-5 <'A' ? 26-5: -5;
- }
- puts(str);
- }
- gets(str);
- }
- return 0;
- }
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Problem C: 小孩报数问题
Description
Input
接下来每行输入一个小孩的名字(人名不超过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
- #include <stdio.h>
- #define PEOPLE_NUM 65
- #define NAME_LEN 16
- struct people
- {
- char name[NAME_LEN];
- char flag;
- };
- void input();
- void calc();
- struct people children[PEOPLE_NUM];
- int n,w,s;
- int main()
- {
- input();
- calc();
- return 0;
- }
- void input()
- {
- int i;
- scanf("%d/n", &n);
- for(i=1; i<=n ;i++)
- {
- gets(children[i].name);
- children[i].flag=0;
- }
- scanf("%d,%d", &w, &s);
- }
- void calc()
- {
- int i ,out ,pos ;
- for(out=0,pos=w-1; out<n ; out++)
- {
- for(i=0; i<s;)
- {
- pos= (pos == n ? 1:pos+1);
- if(children[pos].flag == 0)
- i++;
- }
- puts(children[pos].name);
- children[pos].flag = 1;
- }
- }
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Description
对于给定的采用”yyyy/mm/dd”加24小时制(用短横线”-”连接)来表示日期和时间的字符串,请编程实现将其转换成”mm/dd/yyyy”加12小时制格式的字符串。
Input
接下来的总共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
- #include <stdio.h>
- #include <string.h>
- #define T 10
- #define DATE_LEN 10
- #define TIME_LEN 10
- #define SUM_LEN 22
- static void reverse(char a[], int n);
- void change_date(char date[]);
- void change_time(char time[]);
- int t;
- char datetime[T][SUM_LEN];
- int main()
- {
- int i;
- scanf("%d/n", &t);
- //scanf
- for(i=0; i<t; i++)
- {
- gets(datetime[i]);
- }
- //change date & time
- for(i=0; i<t; i++)
- {
- //date
- change_date(datetime[i]);
- //time
- change_time(datetime[i]+DATE_LEN+1);
- }
- //output
- for(i=0; i<t; i++)
- {
- puts(datetime[i]);
- }
- return 0;
- }
- static void reverse(char a[], int n)
- {
- int i;
- char t;
- for(i=0,n--; i<n-i; i++)
- {
- t = a[i];
- a[i] = a[n-i];
- a[n-i] = t;
- }
- }
- void change_date(char date[])
- {
- reverse(date, 4);
- reverse(date+5, 5);
- reverse(date, DATE_LEN);
- }
- void change_time(char time[])
- {
- if ( (time[0]>='1') && (time[1]>='2') )
- {
- if( (time[0]!='1') || (time[1]!='2') )
- {
- time[0] -= 1;
- time[1] -= 2;
- }
- strcat(time, "pm");
- }
- else
- {
- if( (time[0]=='0') && (time[1]=='0') )
- {
- time[0] += 1;
- time[1] += 2;
- }
- strcat(time, "am");
- }
- }
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Description
Input
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
- #include <stdio.h>
- #include <stdlib.h>
- void calc(char *ma, int m, int n);
- void output(char *ma, int m, int n);
- int main()
- {
- int m=4, n=9;
- char *matrix;
- scanf("%d %d", &m, &n);
- matrix = malloc(m*n*sizeof(char));
- if (matrix == NULL)
- return -1;
- calc(matrix, m, n);
- output(matrix, m, n);
- return 0;
- }
- void output(char *ma, int m, int n)
- {
- int i,j;
- for(i=0; i<m; i++)
- {
- for(j=0; j<n; j++)
- {
- printf("%4c", ma[n*i+j]);
- }
- puts("");
- }
- }
- void calc(char *ma, int m, int n)
- {
- int i=0, j=-1;
- int u,d,l,r,sum;
- sum=0;
- u=0;
- d=m;
- l=0;
- r=n;
- while(1)
- {
- if (l==r)
- break;
- for(j++; j<r; j++)
- {
- ma[n*i+j] = (sum++)%26 +'A';
- }
- u++;
- j--;
- if (u==d)
- break;
- for(i++; i<d; i++)
- {
- ma[n*i+j] = (sum++)%26 +'A';
- }
- r--;
- i--;
- if (l==r)
- break;
- for(j--; j>=l; j--)
- {
- ma[n*i+j] = (sum++)%26 +'A';
- }
- d--;
- j++;
- if (u==d)
- break;
- for(i--; i>=u; i--)
- {
- ma[n*i+j] = (sum++)%26 +'A';
- }
- l++;
- i++;
- }
- }