西邮杯初赛
来源:互联网 发布:一元秒杀包邮 淘宝 编辑:程序博客网 时间:2024/06/05 04:15
问题 A: CONTEST1.加法变乘法(by YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 254 解决: 115
[提交][状态][讨论版]
题目描述
已知X可以写成从1开始连续若干个整数的和, 现在要求把其中两个不相邻的加号变成乘号,使得结果为Y。找出所有满足条件的可能答案并输出(把两个乘号左边的数字用小括号括起来,中间用英文逗号间隔,两个括号之间不空格);若找不到满足的条件,则输出“NONE”字样。编写程序,完成n组数据的判定。
例如:当X为1225,Y为2015时
因为:1+2+3+ ... + 49 = 1225
1+2+3+...+10*11+12+...+27*28+29+...+49 = 2015
所以:一个解为(10,27)。
输入
第一行为n值,接下来依次n行的第一个数据是加法结果X,第二个数据是变乘法后的结果Y,以空格间隔。
输出
输出n行,每一行的格式为“(***,***)(***,***)”(或者“NONE”)。请严格按照格式书写,不能出现其它文字或符号。
样例输入
31225 20151224 20151275 2065
样例输出
(10,27)(16,24)NONE(10,27)(16,24)
双重循环暴力
#include<stdio.h>void fun(int x,int y) {int i;int j;int tmp = 0;int res = 0;int flag = 1;for(i = 2; i <= 10000; i++) { tmp = res = x - (i+(i-1)) + i*(i-1);for(j = i+2; j <= 10000; j++) { res = tmp - (j + (j-1)) + j * (j-1); if(res == y) { printf("(%d,%d)",i - 1,j - 1); flag = 0;}}}if(flag == 1){printf("NONE");}printf("\n");}int main(void) {int n;int X;int Y;scanf("%d",&n);while(n--) {scanf("%d %d",&X,&Y);fun(X,Y); }return 0;}
问题 B: CONTEST2.核桃的数量(BY YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 760 解决: 597
[提交][状态][讨论版]
题目描述
小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:
(1)各组的核桃数量必须相同;
(2)各组内必须能平分核桃(当然是不能打碎的)
(3)尽量提供满足1,2条件的最小数量(节约闹革命嘛)
输入
输入包含三个正整数a,b,c,表示每个组正在加班的人数,用空格分开 (a,b,c均小于30)。
输出
输出一个正整数,表示每袋中核桃的数量,不要输出多余的信息。
样例输入
30 12 9
样例输出
180
求三个数的最小公倍数
#include<stdio.h>int fun(int x,int y); int fun(int x,int y) { int t;int d; if(y > x) { t = x; x = y; y = t; } while(y != 0) { d = y; y = x%y; x = d; } return x; } int main(void) { int x;int y;int z;int n;int m; scanf("%d %d %d",&x,&y,&z); m = x * y / fun(x,y); n = m * z/ fun(z,m); printf("%d\n",n); return 0; }
问题 C: CONTEST3.移动距离(BY YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 758 解决: 332
[提交][状态][讨论版]
题目描述
X星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为1,2,3...当排满一行时,从下一行相邻的楼往反方向排号。
例如:当小区排号宽度为6时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 .....
问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离(不能斜线方向移动)
输入
输入为3个整数w m n,空格分开,都在1到10000范围内。
w为排号宽度,m,n为待计算的楼号。
输出
输出一个整数,表示m n 两楼间最短移动距离。
样例输入
6 8 2
样例输出
4
求点的坐标,奇数行正序,偶数行逆序,曼哈顿距离(横坐标之差绝对值+纵坐标之差绝对值)
#include<stdio.h>#include<math.h>typedef struct node {int x;int y;}node;node fun(int w,int n) {node tmp;tmp.x = (n-1) / w + 1; tmp.y = n % w; if (tmp.y == 0) tmp.y = w; if (tmp.x % 2 == 0) { tmp.y = w - tmp.y + 1; } return tmp;}int main(void) {node tmp_1;node tmp_2;int w;int m;int n;int res;scanf("%d %d %d",&w,&m,&n);tmp_1 = fun(w,m);tmp_2 = fun(w,n);res = abs(tmp_1.x - tmp_2.x) + abs(tmp_1.y - tmp_2.y);printf("%d\n",res);return 0;}
问题 D: CONTEST4.翻硬币(BY YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 458 解决: 293
[提交][状态][讨论版]
题目描述
小明正在玩一个“翻硬币”的游戏,桌上放着排成一排的若干硬币。我们用 * 表示正面, 用 o 表示反面(是小写字母,不是零)。例如,可能情形是:**oo***oooo,如果同时翻转左边的两个硬币,则变为:oooo***oooo。
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作。
输入
两行等长的字符串,分别表示初始状态和要达到的目标状态,每行的长度<1000。
输出
一个整数,表示最小操作步数。
样例输入
**********o****o****
样例输出
5
从左到右遇到不同的就翻一次,就会得到答案
#include<stdio.h>#include<string.h>char a[1001];char b[1001];void fun(int i) { if(a[i] == '*') a[i] = 'o'; else a[i] = '*'; if(a[i+1] != 0) { if(a[i+1] == 'o') a[i+1] = '*'; else a[i+1] = 'o'; } }int main(void) {int count = 0;int len;int i;gets(a);gets(b);len = strlen(a);for(i = 0;i < len;i++) {if(a[i] != b[i]) {fun(i);count++;}}printf("%d\n",count);return 0;}
问题 E: CONTEST5.字符统计(BY YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 445 解决: 297
[提交][状态][讨论版]
题目描述
编写程序接收从键盘输入的n个字符串(1<n<=10),然后实现下列功能:
(1)输出字符串的长度;
(2)输出字符串所包含的单词的数量;
(3)统计该字符串包含的大写字母、小写字母、数字、空格和其他字符的数量并输出。
输入
第一行为n值,以后连续n行为待统计的字符串,每行的长度<100。
每个单词之间用一个空格隔开,或者用一个标点加一个空格隔开。
输出
输出n行,每行是7个整数,依次表示:字符串长度、单词数量、大写字母数量、小写字母数量、数字数量、空格数量、其他字符数量。每个数字以空格隔开,每行最后一个数字后面没有空格。
样例输入
3There are 166 students in the C programming contest.Congratulation, you receive nice scores in this test, please continue.I am very fond of learning advanced language program design courses.
样例输出
52 9 2 38 3 8 170 10 1 57 0 9 368 11 1 56 0 10 1
单词数=空格数+1
#include<stdio.h>#include<string.h>int main(void) {char a[20][101];int len;int kongge;int shuzi;int daxie;int xiaoxie;int qita;int n;int j;int i;scanf("%d",&n);getchar();for(i = 0;i < n;i++) {gets(a[i]);}for(i = 0;i < n;i++) {kongge = 0;shuzi = 0;daxie = 0;xiaoxie = 0;qita = 0;len = strlen(a[i]);for(j = 0;j < len;j++) {if(a[i][j] == ' ') kongge++; else if(a[i][j] >= 'a' && a[i][j] <= 'z') xiaoxie++; else if(a[i][j] >= 'A' && a[i][j] <= 'Z') daxie++; else if(a[i][j] >= '0' && a[i][j] <= '9') shuzi++; else qita++; }printf("%d %d %d %d %d %d %d",len+1,kongge + 1,daxie,xiaoxie,shuzi,kongge,qita);if(i != n-1) printf("\n"); }return 0;}
问题 F: CONTEST6.格式打印(by YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 72 解决: 21
[提交][状态][讨论版]
题目描述
编写程序实现将一段文章格式化打印出来。打印时每行的长度为20个字符。
输入
该段文章长度<=500,单词的数量<=100。
以回车作为该段文章的输入结束。
输出
如果某行仅一个单词,则在该单词结束处直接换行;
否则在每行最后一个单词前增加一些空格,以便使每行的末尾准确地显示在第20个位置处。
样例输入
The relationship between XML functional dependencies and XML keys are also discussed.
样例输出
The relationshipbetween XMLfunctionaldependencies andXML keys are alsodiscussed.
先用gets()接收,然后用二维字符串数组存储单词。然后用start和end确定每行首和下一行开始的单词下标。多于一个注意要右对齐,计算空格的个数。
#include<stdio.h> #include<string.h> int main(void) { char a[10001]; char word[101][100]; char ch; int i; int length; gets(a); int len = strlen(a); int count = 0; int k = 0; for(i = 0;i < len;i++) { if(a[i] != ' ') { word[count][k] = a[i]; k++; } else { k = 0; count++; } } count = count + 1; /*//这样出现段错误,求解 ch = getchar(); while(ch != '\n'){ while(ch == ' ') { ch = getchar(); } i = 0; while( (ch != ' ') && (ch != '\n')) { word[count][i++] = ch; ch = getchar(); } word[count][i] = 0; count++; } count++; */ int start = 0; length = 0; int end = -1; while(end != count) { end = -1; if(length != 1) { length = 0; } for(i = start;i < count;i++) { length += strlen(word[i]); if(length > 20) { end = i; break; } length++; } if(end == -1) end = count; if(end - start == 1) { printf("%s",word[start]); length = 1; } else { int space = 21; for(i = start;i < end;i++) { space -= strlen(word[i]); space--; } for(i = start;i < end - 1;i++) { printf("%s ",word[i]); } for(i = 0;i < space;i++) { printf(" "); } printf("%s",word[end-1]); } printf("\n"); start = end; } return 0; }
问题 G: CONTEST7.可逆素数(BY YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 818 解决: 360
[提交][状态][讨论版]
题目描述
若将某一素数的各位数字顺序颠倒后得到的数仍然是素数,则次素数称为可逆素数。
判断给定的n个数据是否是可逆素数。
输入
第一行为n值,第二行输入n个数字,以空格间隔。
输出
输出n行,每一行的格式为【***是可逆素数】(或者【***是素数,但不是可逆素数】,用中文逗号隔开,或者【***不是素数】)。
请严格按照格式书写,不能出现其它文字或符号。
特别说明:待判断的数据个数不超过10个。
样例输入
323 31 18
样例输出
23是素数,但不是可逆素数31是可逆素数18不是素数
#include<stdio.h>int is_Prime(int n);int is_Prime(int n) {int i;if(n <= 1) {return 0;}else if(n == 2) {return 1;} else {for(i = 2;i < n;i++) {if(n % i == 0){break;}}if(i == n){return 1;}else {return 0;}}}int swap(int n) {int result = 0; int i; if(n == 0) { return result; } while(n > 0) { i = n % 10; n = n / 10; result = result * 10 + i; } return result; }int main(void) {int n;int a[11];int flag_1;int flag_2;int t;int i;scanf("%d",&n);for(i = 0;i < n;i++) {scanf("%d",&a[i]);}for(i = 0;i < n;i++) {flag_1 = 0;flag_2 = 0;if(is_Prime(a[i])) {flag_1 = 1;}t = swap(a[i]);if(is_Prime(t)) {flag_2 = 1;}if(flag_1 == 1 && flag_2 == 1) {printf("%d是可逆素数\n",a[i]);} else if(flag_2 == 0 && flag_1) {printf("%d是素数,但不是可逆素数\n",a[i]);} else {printf("%d不是素数\n",a[i]);}}return 0;}
问题 H: CONTEST8.星系炸弹(by YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 104 解决: 24
[提交][状态][讨论版]
题目描述
在X星系的广袤空间中漂浮着n个X星人造“炸弹”,每个炸弹都可以设定多少天之后爆炸。例如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日,星期五爆炸。
输入
第一行为n值,以后连续n行为炸弹放置日期(格式为 年-月-日)和定时天数(整型)。
输出
输出n行,每行为爆炸的准确日期(格式为 yyyy年mm月dd日 星期几),日期和星期之间用一个空格隔开。请严格按照格式书写,不能出现其它文字或符号。
提示信息:星期的数据集合是【星期日、星期一、星期二、星期三、星期四、星期五、星期六】。1900年1月1日,是星期一。
样例输入
21999-9-9 8002014-11-9 1000
样例输出
2001年11月17日 星期六2017年08月05日 星期六
日期累加,月和年进位。再求日期与1990年1月1日的天数差值,和7取余。注意星期数组的大小。
#include<stdio.h>void fun(int days,int year,int month,int day) {char week[7][28] = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};int monthDays[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; int i; int s = 0;int flag_1 = 0;int flag_2 = 0; for(i=0;i<days;i++) { day++; if(day > monthDays[month-1]) { day=1; month++; if(month > 12) { month=1; year++; if((year%400==0) ||(year%4==0 && year%100!=0)) monthDays[1] = 29; else monthDays[1] = 28; } } } if(month > 9)flag_1 = 1;if(day > 9)flag_2 = 1;if(flag_1 == 1 && flag_2 == 1) {printf("%d年%d月%d日 ",year,month,day);} else if(flag_1 == 0 && flag_2 == 1) {printf("%d年0%d月%d日 ",year,month,day);} else if(flag_1 == 1 && flag_2 == 0) {printf("%d年%d月0%d日 ",year,month,day);} else if(flag_1 == 0 && flag_2 == 0) {printf("%d年0%d月0%d日 ",year,month,day);}if(year >= 1990) {for(i = 1990;i < year;i++) {if((i%400 == 0) || (i%4 == 0 && i%100 != 0)) s += 366;elses += 365;}if((year%400==0) ||(year%4==0 && year%100!=0)) monthDays[1] = 29; else monthDays[1] = 28; for(i = 0;i < month - 1;i++) {s += monthDays[i];}s += day - 1;printf("%s",week[s%7]);} else {for(i = 1990;i > year;i--) {if((i%400 == 0) || (i%4 == 0 && i%100 != 0)) s += 366;elses += 365;} if((year%400==0) ||(year%4==0 && year%100!=0)) monthDays[1] = 29; else monthDays[1] = 28; for(i = 12;i > month;i--) {s += monthDays[i - 1];}s += monthDays[month] - day + 1;printf("%s",week[s%7]);}}int main(void) {int n;int year;int month;int day;int days;scanf("%d",&n);while(n--) {scanf("%d-%d-%d %d",&year,&month,&day,&days);fun(days,year,month,day);printf("\n");}return 0;}
问题 I: CONTEST9.特殊回文数(BY YAN)
时间限制: 10 Sec 内存限制: 256 MB提交: 745 解决: 203
[提交][状态][讨论版]
题目描述
123321是一个非常特殊的数,它从左边读和从右边读是一样的。输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n (1<=n<=54)。
输入
输入一个正整数n。
输出
若特殊回文数的个数<=10,则按从小到大的顺序输出满足条件的特殊回文数,每个数字占一行。
若特殊回文数的个数>10,则仅输出总个数。
样例输入
52
样例输出
899998989989998899
先判断是不是回文数,再判断是否满足条件。用一个数组存储,count小于等于10,输出数组,大于10,输出count。
#include<stdio.h>int h[10001];void fun(int n) { int i; int j; int sum; int temp; int len; int a,b,c; int count = 0;j = 0; for(i = 10000;i < 1000000;++i) { sum = 0; temp = i; len = 0; while(temp != 0) { sum = sum * 10 + temp % 10; temp = temp/10; len++; } if(sum == i){ a = i % 10; b = i / 10 % 10; c = i / 100 % 10; if(5 == len) { if(n==(2*a + 2*b + c)) { h[j++] = i;count++; } } if(6 == len) { if(n == (2*a + 2*b + 2*c)) { h[j++] = i;count++; } } } } if(count <= 10) {for(i = 0;i < count;i++) {printf("%d\n",h[i]);}} else {printf("%d\n",count);}} int main(void) {int n; scanf("%d",&n); fun(n); return 0; }
问题 J: CONTEST10.特大整数的精确相加和相减(by YAN)
时间限制: 10 Sec 内存限制: 512 MB提交: 49 解决: 21
[提交][状态][讨论版]
题目描述
特大整数用长整型也存不下,如果用双精度实型存储则会造成误差,可以用字符数组存储所有位,再按十进制由低到高逐位相加,同时考虑进位。
特别提示:假设特大整数不超过30位。参与操作的数据中,被减数>减数。
算法分析:
1.初始化:将两个特大整数输入两个字符数组,将两个字符数组的各元素右移,使最低位的元素位置对齐,高位补0,为了存储最高位的进位,位数多的数最高位前也应补一个0。
2.从最低位对应的数组元素开始将数字字符转换为整型数据相加,因为数字字符‘0’对应的ASCII值是48,则:整型数据1+2,相当于 ('1'-48)+('2'-48),即'1'+'2'-96。
3.将和整除以10,余数就是该位的结果,并转换为字符(整型数据+48)存入该位,商就是进位数。
4.再对高一位对应的数组元素操作,将该位数字字符转换为整型相加,并与低位的进位数相加,将和整除以10,余数就是该位的结果,商就是本位的进位数。
5.重复4直到最高位。如果最高位相加时进位数大于0则将此进位数转换为字符存入最高位。
输入
第一行待运算的表达式个数n,之后连续的2n行每相邻得两行为一组。
输出
依次输出运算结果,共输出2n行。前n行为相加的运算结果;后n行为相减的运算结果,每个结果独占一行。
样例输入
31234567892345678999999999999999999910000000009999
样例输出
146913578199999999810000099991000000000999990001
模拟竖式的手工过程
#include<stdio.h>#include<string.h>#include<stdlib.h>void swap(char target[]) {int i;int j;char temp;for(i = 0,j = strlen(target) - 1;i <= j;i++,j--) {temp = target[i];target[i] = target[j];target[j] = temp;}}void BigNumAdd(char a[],char b[]) {int i;char c[1001] = {0};swap(a);swap(b);for(i = 0;i < strlen(a) && i < strlen(b);i++) {c[i] += a[i] + b[i] - '0'; if(c[i] - '0' >= 10){ c[i] = c[i] - 10; c[i+1] = 1; }}if(strlen(a) == strlen(b)) { if(c[i] == 1) c[i]='1';}if(strlen(a) > strlen(b)){ if(c[i] == 1) { for(;i < strlen(a);i++){ c[i] += a[i]; if(c[i] - '0' >= 10) { c[i] = c[i] - 10; c[i+1] = 1; } } if(c[i-1] == '0')c[i] = '1'; }else { for(;i < strlen(a);i++)c[i] = a[i];}} if(strlen(b) > strlen(a)){ if(c[i]==1){ for(;i < strlen(b);i++){ c[i] += b[i]; if(c[i] - '0' >= 10){ c[i] = c[i] - 10; c[i+1] = 1; } }if(c[i] == 1)c[i] = '1';} else { for(;i < strlen(b);i++)c[i] = b[i];}}swap(c);printf("%s\n",c);}void BigNumChange(char *str1, char *str2) { int len1 = strlen(str1); int len2 = strlen(str2); int i; int *num1 = (int*)malloc(len1*sizeof(int)); int *num2 = (int*)malloc(len1*sizeof(int)); if(str1 == NULL || str2 == NULL) return; for (i = 0; i < len1; i++) { num1[i] = num2[i] = 0; } for (i = len1 - 1; i >= 0; i--) { num1[len1 - 1 - i] = str1[i] - '0'; } for (i = len2 - 1; i >= 0; i--) { num2[len2-1-i] = str2[i] - '0'; } for (i = 0; i < len1; i++) { num1[i] = num1[i] - num2[i]; if(num1[i] < 0) { num1[i] = num1[i] + 10; num1[i+1] = num1[i+1] - 1; } } for (i = len1-1; i>=0 && num1[i] == 0; i--) ; if(i >= 0) for (; i >= 0; i--) { printf("%d",num1[i]); } else printf("0"); } int main(void) {int n;char a[100][100];int i;int len1;int len2;scanf("%d",&n);for(i = 0;i < 2*n;i++) {scanf("%s",a[i]);}for(i = 0;i < 2*n;i += 2) {BigNumAdd(a[i],a[i+1]);}for(i = 0;i < 2*n;i++) {swap(a[i]);}for(i = 0;i < 2*n;i += 2) {len1 = strlen(a[i]);len2 = strlen(a[i+1]);if(len1 > len2) {BigNumChange(a[i],a[i+1]);} else if(len1 < len2) {printf("-");BigNumChange(a[i+1],a[i]);} else {if(strcmp(a[i],a[i+1]) >= 0) {BigNumChange(a[i],a[i+1]);} else {printf("-");BigNumChange(a[i+1],a[i]);}}printf("\n");}return 0;}
最后推荐一个大佬的题解http://blog.csdn.net/hepangda/article/details/73431191
- 西邮杯初赛
- NOIP2009初赛
- 初赛前夕
- 初赛整理
- 初赛复习
- NOIP2016 初赛
- 初赛复习
- 氮氧碘磷初赛
- 初赛日志
- 初赛经验总结
- 第一次初赛
- 初赛总结
- 初赛方案完成~~
- 初赛方案提交了!
- 准备TMT初赛中
- 初赛文档雏形完成
- 初赛,复赛,决赛
- 顶嵌杯(初赛)
- 【51Nod 1789】跑的比谁都快
- 多线程中线程停止的问题
- Java中常用的设计模式
- USACO-Section1.5 SuperPrime Rib [质数]
- Roads and Libraries
- 西邮杯初赛
- PAT甲级 1006
- 分享马化腾在3Q大战后写给腾讯全体员工的一封信
- C++设计模式之观察者模式
- 简单使用makefile V1.0
- 数通平台软件中的概念:组件
- 你所不知道的腾讯和马化腾——一封腾讯内部的员工信
- 多线程应用场景
- 精 挑 细 选