问题 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”)。请严格按照格式书写,不能出现其它文字或符号。
样例输入
样例输出
双重循环暴力
#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)。
输出
输出一个正整数,表示每袋中核桃的数量,不要输出多余的信息。
样例输入
样例输出
求三个数的最小公倍数
#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 两楼间最短移动距离。
样例输入
样例输出
求点的坐标,奇数行正序,偶数行逆序,曼哈顿距离(横坐标之差绝对值+纵坐标之差绝对值)
#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。
输出
一个整数,表示最小操作步数。
样例输入
样例输出
从左到右遇到不同的就翻一次,就会得到答案
#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个整数,依次表示:字符串长度、单词数量、大写字母数量、小写字母数量、数字数量、空格数量、其他字符数量。每个数字以空格隔开,每行最后一个数字后面没有空格。
样例输入
样例输出
单词数=空格数+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个位置处。
样例输入
样例输出
先用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个。
样例输入
样例输出
#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日,是星期一。
样例输入
样例输出
日期累加,月和年进位。再求日期与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;
else
s += 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;
else
s += 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,则仅输出总个数。
样例输入
样例输出
先判断是不是回文数,再判断是否满足条件。用一个数组存储,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行为相减的运算结果,每个结果独占一行。
样例输入
样例输出
模拟竖式的手工过程
#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