3.3 几道简单的竞赛题目
例题 3-1 Tex中的引号
在TeX中,左引号是”””,右引号是““”。输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式。
样例输入:
“To be or not to be,”quoth the Bard,”that
is the question”.
样例输出:
”To be or not to be,“quoth the Bard,”that
is the question“.
程序 3-1 Tex中的引号
#include<stdio.h> int main() { int c, flag = 1; //从stdio流中读字符,相当于getc(stdin),它从标准输入里读取下一个字符。返回类型为int型,返回值为用户输入的ASCⅡ码,出错返回-1。 while (c = getchar()) { if (c == '"') { printf("%c", flag ? "“" : "”"); flag = !flag; } else { printf("%c", c); } } return 0; }
此题在编译过程中 code::blocks 报 converting to execution character set: Illegal byte sequence 错误。原因是程序中出现了中文字符,而默认的是UTF-8编码,所以就出现了这样的问题。
解决方法:
在使用gcc或者g++编译文件时,命令参数加上一句:-finput-charset=GBK
截图如下:
例题 3-2 QWERTYU
把手放在键盘上是,稍不注意就会往右错一位。这样,输入 Q 会变成 W,输入 J 就会变成输入 K 等。
输入一个错位后敲出的字符串(所有子母均大写),输出打字员本来想当打出的句子。输入保证合法,即一定是错位之后的字符串,例如输入中不会出现大写字母 A。
样例输入:
O S, GOMR YPFSU/
样例输出:
I AM FINE TODAY.
程序 3-2
#include<stdio.h> #include<string.h> int main() { int c; //使用常量数组,简单高效 char str[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./"; while (c = getchar()) { //找到错位之后的字符在常量数组中的位置 for (int i =0; i < strlen(str); i++) { //如果找到,则输出前一字符,并退出循环 if (c == str[i]) { printf("%c", str[i-1]); break; } } //留意判断空格 if (c == ' ') printf("%c", c); } return 0; }
例题 3-3 回文数
输入一个字符串,判断它是否为回文串以及镜像串,输入字符串保证不含数字0。
程序 3-3
#include<stdio.h> #include<string.h> //For isalpha #include<ctype.h> char str[50]; //常量数组。前26项是各字幕的镜像,后10项是个数字对应的镜像 const char rec[] = "A 3 HIL JM O 2TUVWXY51SE Z 8 "; char r(char ch) { //isalpha判断字符是否为字母,类似还有idigit, isprint 在ctype.h中 if (isalpha(ch)) { //在ASC码中,大写字母,小写字母和数字是连续的。 //如果如果一个字符是大写字母则其减去 ‘A’是其在字母表中的序号 return rec[ch - 'A']; } else { return rec[ch - '0' +25]; } } int main() { while (scanf("%s", str) == 1) { int len = strlen(str); bool ishui = true, isjin = true; for (int i = 0; i < len; i++) { if (str[i] != str[len -1 -i] && ishui) { ishui = false; } if (r(str[i]) != str[len - 1 -i]) { isjin = false; } } if (ishui) { printf("是回文数"); } else { printf("不是回文数 "); } if (isjin) { printf("是镜像数\n"); } else { printf("不是镜像数\n"); } } return 0; }
例题 3-5 生成元
如果 x 加上 x 的各个位数数字之和得到 y,就说 x 是 y 的生成元。给出n(1 <= n <= 100000),求最小生成元。无解输出0.
例如,n=216,121,2005时的解分别为198,0,1979
程序 3-5
#include<stdio.h> #include<string.h> // int ans[100005]; int main() { //数组置零 memset(ans, 0, sizeof(ans)); for (int i = 1; i < 100000; i++) { int temp = 0, sum = i,x = i; //逐步分解各个数位上的数字 while (x > 0) { temp = x % 10; sum += temp; x = x /10; } //制成表,输入数组下标,输出生成元 if (ans[sum] == 0) { ans[sum] = i; } } int digit = 0; while (scanf("%d", &digit) == 1) { //因为数组已经置零,而无解输出也是零,因此可以不进行判断是否无解,而直接输出 printf("%d\n", ans[digit]); } return 0; }
例题 3-6 DNA环状序列,求字典序最小
程序 3-6
#include <stdio.h> #include <string.h> #define MAXN 105 // p 为下一个字符串起始编号, q 为当前最优编号 int less(const char* s, int p, int q) { int n = strlen(s); for(int i = 0; i < n; i++) { //绕成环用对 n 取余解决 if(s[(p+i)%n] != s[(q+i)%n]) return s[(p+i)%n] < s[(q+i)%n]; } return 0; } int main() { //存在 T 组输入 int T; char s[MAXN]; scanf("%d", &T); while(T--) { scanf("%s", s); int ans = 0; int n = strlen(s); for(int i = 1; i < n; i++) { if(less(s, i, ans)) ans = i; } for(int i = 0; i < n; i++) { putchar(s[(i+ans)%n]); } putchar('\n'); } return 0; }