1.加法变乘法
已知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”)。请严格按照
格式书写,不能出现其它文字或符号
样例
3
1225 2015
1224 2015
1275 2065
(10,27)(16,24)
NONE
(10,27)(16,24)
题解:用X和Y减去变化的量,最后结果相同即可。
源代码:
#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++) {
for(j = i+2; j <= 10000; j++) {
tmp=x-i*2-j*2-2;
res=y-i*(i+1)-j*(j+1);
if(res == tmp) {
printf("(%d,%d)",i ,j );
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;
}
2.核桃的数量
小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。
为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。
他的要求是:
(1)各组的核桃数量必须相同;
(2)各组内必须能平分核桃(当然是不能打碎的)
(3)尽量提供满足1,2条件的最小数量
输入
输入包含三个正整数a,b,c,表示每个组正在加班的人数,用空格分开 (a,b,c均小于30)
输出
输出一个正整数,表示每袋中核桃的数量,不要输出多余的信息。
样例
30 12 9
180
题解:此题即求三个数的最小公倍数。
源代码
#include<stdio.h>
int max(int a,int b,int c)
{
if(a>b&&a>c)
return a;
else if(b>a&&b>c)
return b;
else
return c;
}
int main()
{
int x,y,z,i,j,k;
scanf("%d%d%d",&x,&y,&z);
k = max(x,y,z);
i= 1;
while(1)
{
j = k * i;
if((j%x==0)&&(j%y==0)&&(j%z==0))
break;
i++;
}
printf("%d\n",j);
return 0;
}
3.翻硬币
小明正在玩一个“翻硬币”的游戏,桌上放着排成一排的若干硬币。
我们用 * 表示正面, 用 o 表示反面(是小写字母,不是零)。
例如,可能情形是:**oo***oooo,
如果同时翻转左边的两个硬币,则变为:oooo***oooo。
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币
那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作。
输入
两行等长的字符串,分别表示初始状态和要达到的目标状态,每行的长度<1000。
输出
一个整数,表示最小操作步数。
样例
**********
o****o****
5
题解:如果初始状态和目标状态不一致则同时翻转两个相邻的硬币,每翻转一次计数器加1。
源代码
#include<stdio.h>
#include<string.h>
#define maxn 1002
void change(char str[],int i)
{
str[i]=str[i]=='*'?'o':'*';
}
int main()
{
char str1[maxn],str2[maxn];
scanf("%s%s",str1,str2);
int i=0,tot=0;
int l=strlen(str1);
while(i < l-1)
{
if(str2[i]!=str1[i])
{
tot++;
change(str2,i);
change(str2,i+1);
}
i++;
}
printf("%d\n",tot);
return 0;
}
4.格式打印
编写程序实现将一段文章格式化打印出来。打印时每行的长度为20个字符。
输入
该段文章长度<=500,单词的数量<=100。
以回车作为该段文章的输入结束。
输出
如果一行的最后一个单词超过了本行的20个字符的范围,则应把它移到下一行;
如果某行仅一个单词,则在该单词结束处直接换行;
否则在每行最后一个单词前增加一些空格,以便使每行的末尾准确地显示在第20个位置处。
样例
The relationship between XML functional dependencies and XML keys are also discussed.
The relationship
between XML
functional
dependencies and
XML keys are also
discussed.
题解
先用gets()接收,然后用二维字符串数组存储单词。然后用start和end确定每行首和下一行开始的单词下标。多于一个注意要右对齐,计算空格的个数。
源代码
#include<stdio.h>
#include<string.h>
int main()
{
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++;
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;
}
5.星系炸弹
在X星系的广袤空间中漂浮着n个X星人造“炸弹”,每个炸弹都可以设定多少天之后爆炸。例如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日,星期五爆炸。
输入
第一行为n值,以后连续n行为炸弹放置日期(格式为 年-月-日)和定时天数(整型)。
输出
输出n行,每行为爆炸的准确日期(格式为 yyyy年mm月dd日 星期几),日期和星期之间用一个空格隔开。请严格按照格式书写,不能出现其它文字或符号。
提示信息:星期的数据集合是【星期日、星期一、星期二、星期三、星期四、星期五、星期六】。1900年1月1日,是星期一。
样例
2
1999-9-9 800
2014-11-9 1000
2001年11月17日 星期六
2017年08月05日 星期六
题解
时间推移,万年历问题
源代码
#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;
}
6.特大整数的相加和相减
特大整数用长整型也存不下,如果用双精度实型存储则会造成误差,可以用字符数组存储所有位,再按十进制由低到高逐位相加,同时考虑进位。
特别提示:假设特大整数不超过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行为相减的运算结果,每个结果独占一行。
样例
3
123456789
23456789
999999999
999999999
1000000000
9999
146913578
1999999998
1000009999
100000000
0
999990001
题解
由于数字过大,所以此题无法直接相加减,所以此题只能运用数组,手动模拟算式过程
源代码
#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;
}
7.可逆素数
若将某一素数的各位数字顺序颠倒后得到的数仍然是素数,则次素数称为可逆素数。
判断给定的n个数据是否是可逆素数。
输入
第一行为n值,第二行输入n个数字,以空格间隔。
输出
输出n行,每一行的格式为【***是可逆素数】(或者【***是素数,但不是可逆素数】,用中文逗号隔开,或者【***不是素数】)。
请严格按照格式书写,不能出现其它文字或符号。
特别说明:待判断的数据个数不超过10个。
样例
3
23 31 18
23是素数,但不是可逆素数
31是可逆素数
18不是素数
题解
先判断是否为素数,再将此数颠倒顺序,判断是否为可你素数(素数的判断条件:除1和他本身以外没有其他的因数)
源代码
#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++) { //此处判断可简化为n/2,或者根号n
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;
}
8.生日蜡烛
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛,设他一共吹熄了n根蜡烛。
请问:他从多少岁开始过生日party的?
输入
输入一共吹的蜡烛个数n
输出
开始过生日的年龄 现在的年龄
样例
236
26 33
源代码
#include <stdio.h>
int main()
{
int i = 1, j, sum = 0;
int n;
scanf("%d",&n);
while(sum != n)
{
for(j = i; ; j++)
{
sum = sum + j;
if(sum > n)
{
sum = 0;
break;
}
else if(sum == n&& i <n)
{
printf("%d %d", i,j);
break;
}
}
i++;
}
return 0;
}
9.移动字母
2×3=6个方格中放入ABCDE五个字母,右下角的那个格空着。如图所示。
1
和空格子相邻的格子中的字母可以移动到空格中,比如,图中的C和E就可以移动,移动后的局面分别是:
A B
D E C
A B C
D E
为了表示方便,我们把6个格子中字母配置用一个串表示出来,比如上边的两种局面分别表示为:
AB*DEC
ABCD*E
题目的要求是:请编写程序,由用户输入若干表示局面的串,程序通过计算,输出是否能通过对初始状态经过若干次移动到达该状态。可以实现输出1,否则输出0。初始状态为:ABCDE*
输入
一个整数n
n行的状态
输出
n行0或1
样例
3
ABCDE*
AB*DEC
CAED*B
1
1
0
源代码
#include<stdio.h>
#include<string.h>
int vis[6];
int TF[100],count;
char temp[]="ABCDE*";
void Getstar(char array[],int *row,int *column)
{
int i;
for (i = 0; i < 6; i++)
{
if (array[i] == '*')
{
*row = i - 3 < 0 ? 0 : 1;
*column = i % 3;
}
}
}
void Print(int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%d\n",TF[i]);
}
}
void swap(char *a,char *b)
{
char T = *a;
*a = *b;
*b = T;
}
void fun(char *cur,int row,int column)
{
int i,x,y;
int a[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
if(!strcmp(cur,temp))
{
TF[count] = 1;
return;
}
else
{
for(i = 0; i < 4; i++)
{
x = row + a[i][0];
y = column + a[i][1];
if((x >= 0 && x <= 1) && (y >= 0 && y <= 2) && !vis[3 * x + y])
{
swap(cur + 3 * row + column,cur + 3 * x + y);
vis[3 * x + y] = 1;
fun(cur,x,y);
swap(cur + 3 * row + column,cur + 3 * x + y);
vis[3 * x + y] = 0;
}
}
}
}
int main()
{
int n,row,column,i;
char array[7];
scanf("%d",&n);
i = n;
while (i)
{
scanf("%s",array);
Getstar(array,&row,&column);
fun(array,row,column);
count++;
i--;
}
Print(n);
return 0;
}
10.按价格排序并输出
一道简单的结构体排序输出问题 ,原题看不见了,原谅我语文不好,自行看代码吧。
注:使用结构体的时候一定要分配空间不然容易乱码
源代码
#include <stdio.h>
#include <malloc.h>
struct Student
{
int num;
float price;
char name[100];
char editor[100];
char chubanshe[100];
int year;
int month;
int day;
};
int main(void)
{
struct Student * pst;
struct Student tst;
int i, j, m, n;
int len;
scanf("%d", &len);
pst= (struct Student *)malloc(len * sizeof(struct Student));
for(i = 0; i<len; i++)
{
scanf("%d", &pst[i].num);
scanf("%s", pst[i].name);
scanf("%s", pst[i].editor);
scanf("%s", pst[i].chubanshe);
scanf("%d-%d-%d", &pst[i].year,&pst[i].month,&pst[i].day);
scanf("%f", &pst[i].price);
}
for(m=0; m<len; m++)
{
for(n = 0; n<len-1-m;n++)
if(pst[n].price > pst[n+1].price)
{
tst = pst[n];
pst[n] = pst[n+1];
pst[n+1] = tst;
}
}
printf("编号 书名 作者 出版社 出版日期 价格\n");
for(j = 0; j<len; j++)
{
printf("%d ", pst[j].num);
printf("%s ", pst[j].name);
printf("%s ", pst[j].editor);
printf("%s ", pst[j].chubanshe);
printf("%d年%d月%d日 ", pst[j].year,pst[j].month,pst[j].day);
printf("%.2f", pst[j].price);
printf("\n");
}
return 0;
}