1009 说反话
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:
测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。
输出格式:
每个测试用例的输出占一行,输出倒序后的句子。
输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello
代码:
#include<stdio.h> #include<string.h> int main() { char str[100];//保存字符串 gets(str); int len = strlen(str);//得到字符长度 char reverse[90][90];//定义一个二维数组,用于保存每个单词 int j = 0, k = 0;//j为单词个数,k为单词长度 for (int i = 0; i < len; i++) {//将字符串的每个单子保存到二维数组中 //如果当前扫描到的字符串的字符为空格,则为当前二维数组加上'\0'终止符,并且移动到下个数组 if (str[i] == ' ') { reverse[j][k] = '\0'; j++; k = 0; } else {//如果当前扫描到的字符串的字符不是空格,则一次保存到二维数组中,并且长度+1 reverse[j][k] = str[i]; k++; } } reverse[j][k] = '\0';//执行循环后,为最后一个单词加上终止符'\0' while (j >= 0) {//循环输出,PAT特色输出 if (j != 0) { printf("%s ", reverse[j]); } else { printf("%s", reverse[j]); } j--; } return 0; }
1014 福尔摩斯的约会
大侦探福尔摩斯接到一张奇怪的字条:
我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm
大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间星期四 14:04
,因为前面两字符串中第 1 对相同的大写英文字母(大小写有区分)是第 4 个字母 D
,代表星期四;第 2 对相同的字符是 E
,那是第 5 个英文字母,代表一天里的第 14 个钟头(于是一天的 0 点到 23 点由数字 0 到 9、以及大写字母 A
到 N
表示);后面两字符串第 1 对相同的英文字母 s
出现在第 4 个位置(从 0 开始计数)上,代表第 4 分钟。现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。
输入格式:
输入在 4 行中分别给出 4 个非空、不包含空格、且长度不超过 60 的字符串。
输出格式:
在一行中输出约会的时间,格式为 DAY HH:MM
,其中 DAY
是某星期的 3 字符缩写,即 MON
表示星期一,TUE
表示星期二,WED
表示星期三,THU
表示星期四,FRI
表示星期五,SAT
表示星期六,SUN
表示星期日。题目输入保证每个测试存在唯一解。
输入样例:
3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm
输出样例:
THU 14:04
注意点:
- 判断星期数的时候,仅需'A'-'G'
- 判断小时数的时候,仅需'0'-'9'和'A'-'N'
测试点示例:
测试一 3485djDkxh4hhG0 2984akDfkkkkgg0dsb s&hgfdkiggggs d&Hycvnmzzzzs 输出 THU 00:12 测试二: HcCO2eA HcCO2eB cCaseC cCaseD 输出 WED 02:00
代码:
(1)
#include<stdio.h> #include<string.h> char DAY[10][5] = { "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" };//定义输出星期几的数组 char transferDay[10] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };//定义星期天数的顺序,方便输出下标 //定义小时数的顺序,方便输出下标 char transferHour[25] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N' }; const int dayMax = 7;//一个星期天数的最大值 const int hourMax = 24;//一天小时数的最大值 char match1(char* a, char* b, int c, int* d) {//匹配星期几 int i; for (i = 0; i < c; i++) { if (a[i] >= 'A' && a[i] <= 'G') {//当前扫描到ASCII码中'A'-'G'时判断 if (a[i] == b[i]) {//如果两个数组的下标相同的字符相等 break;//跳出循环 } } } *d = i;//保存下标 return a[i];//返回相同的字符 } char match2(char* a, char* b, int c, int d) {//匹配小时数 int i; for (i = c + 1; i < d; i++) {//从上次相同的字符的下一个元素开始遍历 if ((a[i] >= '0' && a[i] <= '9') || (a[i] >= 'A' && a[i] <= 'N')) {//当前扫描的元素为'0'-'9'或者'A'-'N'时 if (a[i] == b[i]) {//如果两个数组的下标相同的字符相等 break;//跳出循环 } } } return a[i];//返回相同的元素 } int match3(char* a, char* b, int c) {//判断分钟数 int i; for (i = 0; i < c; i++) { if ((a[i] >= 'a' && a[i] <= 'z') || (a[i] >= 'A' && b[i] <= 'Z')) {//当前扫描的元素是'a'-'z'或'A'-'Z'时 if (a[i] == b[i]) {//如果两个数组的下标相同的字符相等 break;//跳出循环 } } } return i;//返回数组元素下标 } int transferDaySequence(char a, char* b) {//判断当前的字符在星期的顺序数 int i; for (i = 0; i < dayMax; i++) { if (a == b[i]) {//扫描到的字符相等 break;//跳出循环 } } return i; } int transferHourSequence(char a, char* b) {//判断输出小时数 int i; for (i = 0; i < hourMax; i++) { if (a == b[i]) {//扫描到的字符相等 break;//跳出循环 } } return i; } int main() { char str[4][80]; gets(str[0]); gets(str[1]); gets(str[2]); gets(str[3]); int len0 = strlen(str[0]); int len1 = strlen(str[1]); int len2 = strlen(str[2]); int len3 = strlen(str[3]); len0 = (len0 < len1) ? len0 : len1;//保存两个数组中更小的长度 int firstMatch = 0;//保存第一次扫描到的数组下标 char daySequence = match1(str[0], str[1], len0, &firstMatch);//得到相同字符 int day = transferDaySequence(daySequence, transferDay);//得到星期数的顺序下标 char resDay[5]; strcpy(resDay, DAY[day]);//拷贝字符串得到最终结果 char hourSequence = match2(str[0], str[1], firstMatch, len0);//得到相同字符 int resHour = transferHourSequence(hourSequence, transferHour);//得到小时数 len2 = (len2 < len3) ? len2 : len3;//保存两个数组中更小的长度 int resMinute = match3(str[2], str[3], len2);//得到分钟数 printf("%s %02d:%02d", resDay, resHour, resMinute); return 0; }
(2)
#include<stdio.h> #include<string.h> int main(){ char week[7][5] = { "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" }; char str1[70], str2[70], str3[70], str4[70]; gets(str1); gets(str2); gets(str3); gets(str4); int len1 = strlen(str1); int len2 = strlen(str2); int len3 = strlen(str3); int len4 = strlen(str4); int i; //寻找str1和str2中第一队相同位置的A-G的大写字母 for (i = 0; i < len1 && i < len2; i++){ if(str1[i] == str2[i] && str1[i] >= 'A' && str1[i] <= 'G'){ printf("%s ", week[str1[i] - 'A']);//输出星期几 break; } } //往后寻找第二个相同元素,范围为0-9或A-N for (i++; i < len1 && i < len2; i++){ if(str1[i] == str2[i]){ if(str1[i] >= '0' && str1[i] <= '9'){ printf("%02d:", str1[i] - '0');//输出0-9 break; } else if(str1[i] >= 'A' && str1[i] <= 'N'){ printf("%02d:", str1[i] - 'A' + 10);//输出10-23 break; } } } //寻找str3和str4第一对相同元素,范围为A-Z或a-z for (i = 0; i < len3 && i < len4; i++){ if(str3[i] == str4[i]){ if((str3[i] >= 'A' && str3[i] <='Z') || (str3[i] >= 'a' && str3[i] <= 'z')){ printf("%02d", i);//输出当前下标 break; } } } return 0; }
1024 科学计数法
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].
[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。
现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。
输入格式:
每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。
输出格式:
对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。
输入样例 1:
+1.23400E-03
输出样例 1:
0.00123400
输入样例 2:
-1.2E+10
输出样例 2:
-12000000000
代码:
(1)
#include<stdio.h> #include<string.h> int main() { char num[10020];//指数绝对值不超过9999,测试点6 gets(num); int i, locateE, locatePoint, power = 0;//locateE用来存储E的位置,locatePoint用来存储.的位置,power用来存储指数 int len = strlen(num);//得到字符串的长度 for (i = 0; i < len; i++) {//确定E和小数点的位置 if (num[i] == 'E') { locateE = i; } if (num[i] == '.') { locatePoint = i; } } if (num[0] == '-') {//如果是负数,则输入负号 printf("-"); } for (int j = locateE + 2; j < len; j++) {//得到指数 power *= 10; power += num[j] - '0'; } if (num[locateE + 1] == '+') {//如果指数是正数 if (power >= locateE - locatePoint - 1) {//判断指数是否大于小数的位数 for (int j = 1; j < locateE; j++) {//输出所有数字,包括小数 if (num[j] != '.') {//判断当前的字符是不是. printf("%c", num[j]); } } for (int j = 0; j < power - locateE + locatePoint + 1; j++) {//输出多余的0 printf("0"); } } else { for (int j = 1; j < locatePoint + power + 1; j++) {//输出整数部分 if (num[j] != '.') { printf("%c", num[j]); } } printf(".");//输出. for (int j = locatePoint + power + 1; j < locateE; j++) {//输出小数部分 printf("%c", num[j]); } } } else {//如果幂次方是负数 if (power == 0) {//如果指数为0 for (int j = 1; j < locateE; j++) { printf("%c", num[j]);//输出本来的数字 } } else if (power >= 1) {//如果指数大于1 printf("0.");//输出0.前缀 for (int j = 0; j < power - 1; j++) {//输出多余的0 printf("0"); } for (int j = 1; j < locateE; j++) {//输出数字 if (num[j] != '.') { printf("%c", num[j]); } } } } return 0; }
(2)
#include<stdio.h> #include<string.h> int main(){ char str[10010]; gets(str); int len = strlen(str); if (str[0] == '-'){//如果是负数,输出负号 printf("-"); } int pos = 0;//pos存放字符串中E的位置 while (str[pos] != 'E'){ pos++; } int exp = 0;//exp保存指数 for (int i = pos + 2; i < len; i++){ exp = exp * 10 + (str[i] - '0'); } if (exp == 0){//判断指数为0 for (int i = 1; i < pos; i++){ printf("%c", str[i]); } } if (str[pos + 1] == '-'){//如果指数为负 printf("0."); for (int i = 0; i < exp - 1; i++){//输出(exp - 1)个0 printf("0"); } printf("%c", str[1]);//输出除了小数点意外的数字 for (int i = 3; i < pos; i++){ printf("%c", str[i]); } } else{//如果指数为正 for (int i = 1; i < pos; i++){ if(str[i] == '.'){//略过原小数点 continue; } printf("%c", str[i]);//输出当前数位 if(i == exp + 2 && pos - 3 != exp){//小数点加上位置(exp + 2)上 //原小数点和E之间的数字个数(pos -3)不能等于小数点右移位数exp printf("."); } } //如果指数exp更大,输出多余的0 for (int i = 0; i < exp - (pos - 3); i++){ printf("0"); } } return 0; }
1048 数字加密
本题要求实现一种数字加密方法。首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 10、Q 代表 11、K 代表 12;对偶数位,用 B 的数字减去 A 的数字,若结果为负数,则再加 10。这里令个位为第 1 位。
输入格式:
输入在一行中依次给出 A 和 B,均为不超过 100 位的正整数,其间以空格分隔。
输出格式:
在一行中输出加密后的结果。
输入样例:
1234567 368782971
输出样例:
3695Q8118
代码:
(1)
#include<stdio.h> #include<string.h> char odd[15] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'Q', 'K' }; char oddNum(char* a, char* b, int c, int d) {//奇数位 int temp = a[c] - '0' + b[d] - '0';//得到两个数列相应元素数字的合 temp %= 13;//对13取余 return odd[temp];//返回odd数列的结果 } int evenNum(char* a, char* b, int c, int d) {//偶数位 int temp = b[d] - '0' - a[c] + '0';//B - A if (temp < 0) {//如果结果为负数,+10 temp += 10; } return temp; } int main() { char str1[110], str2[110]; scanf("%s", str1); scanf("%s", str2); int len1 = strlen(str1); int len2 = strlen(str2); int temp1; char temp2; if (len2 > len1) {//当B的长度 > A时 for (int i = 0; i < len2 - len1; i++) {//输出B比A长的部分 printf("%c", str2[i]); } for (int i = 0, j = len2 - len1; i < len1; i++, j++) {//遍历A和B剩余的字符串 if ((len1 - i) % 2 != 0) {//奇数 temp2 = oddNum(str1, str2, i, j); printf("%c", temp2); } else {//偶数 temp1 = evenNum(str1, str2, i, j); printf("%d", temp1); } } } else {//B长度 <= A时 int j; char str3[110]; for (j = 0; j < len1 - len2; j++) {//补str1和str2长度差额的0 str3[j] = '0'; } str3[j] = '\0';//添加终止符 strcat(str3, str2);//将str2的字符串内容添加到str3后 for (int i = 0; i < len1; i++) {//遍历字符串,因为str1和str3长度相等,仅需遍历str1 if ((len1 - i) % 2 != 0) {//奇数 temp2 = oddNum(str1, str3, i, i); printf("%c", temp2); } else {//偶数 temp1 = evenNum(str1, str3, i, i); printf("%d", temp1); } } } return 0; }
(2)
#include<stdio.h> #include<string.h> char A[110], B[110], ans[110]; void reverse(char* s){//反转字符串 int len = strlen(s); for (int i = 0; i < len / 2; i++){//交换s[i]和s[len - 1 - i] int temp = s[i]; s[i] = s[len - 1 - i]; s[len - 1 - i] = temp; } } int main(){ scanf("%s %s", A, B);//整数A和B reverse(A); reverse(B); int lenA = strlen(A);//A长度 int lenB = strlen(B);//B长度 int len = lenA > lenB ? lenA : lenB;//A和B较大长度 for(int i = 0; i < len; i++){//从低位开始 int numA = i < lenA ? A[i] - '0' : 0;//numA对应A[i] int numB = i < lenB ? B[i] - '0' : 0;//numB对应B[i] if(i % 2 ==0){//当前位i是偶数 int temp = (numB + numA) % 13;//和再模13 if(temp == 10) ans[i] = 'J';//特判10、11、12 else if (temp == 11) ans[i] = 'Q'; else if (temp == 12) ans[i] = 'K'; else ans[i] = temp + '0';//0-9 } else{//当前位i是奇数 int temp = numB - numA;//差 if(temp < 0) temp += 10;//如果小于0,加上10 ans[i] = temp + '0';//赋对应字符 } } reverse(ans);//反转字符串 puts(ans);//输出结果 return 0; }