输入该方程中各项的系数(a,b,c,d 均为实数)
输出格式:
由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
#include
intmain()
{floata,b,c,d,x;
inti;
scanf("%f%f%f%f",&a,&b,&c,&d);
for(i=-10000;i<=10000;i++)
{x=i/100.0;
if((a*x*x*x+b*x*x+c*x+d>-0.0001)&&(a*x*x*x+b*x*x+c*x+d<0.0001))
printf("%.2f",x);
}
return0;
}
Tip:
直接暴力枚举就行了,扩大100倍可以忽略实数误差。
注意整型/实型才是实型,所以那个100必须写成100.0。
3.松鼠吃果子
有N个一种松鼠喜欢吃的果子由下向上串排成一列,并标号1,2,...N。
一只松鼠从最下果子开始向上跳,并且第i次跳可以一次跳过i*i*i除以5的余数+1个果子(=i*i*i%5+1),并把脚下的果子吃了,如果上面有果子,在重力作用下,都将向下掉下一格。
如第1次跳从第一个果子上跳过1*1*1%5+1=2个果子,可跳到第3个果子上,并把第3个果子吃了;第2次从第4个果子上(落在原来第三个果子位置)跳过2*2*2%5+1=4个到第8个果子上,并把第8个吃了;如此...当然,总有一次松鼠会跳出这串果子的最前面,设为每K次,它吃不到任何果子了。
这时它回到最下面的果子上,重做它的第K次跳,以求吃到果子。
如此,问它吃的第m只果子(即第M跳吃到的果子)的标号是什么?
输入格式:
一共两行,分别为N和m。
(1<=m<=n<=200,并且满足能够跳到第m次)
输出格式:
一个数,即它吃的第m只果子的标号。
#include
#include
intmain()
{inti,j,n,m,guo[201],step,height=1,num;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)guo[i]=i;
for(i=1;i<=m;i++)
{step=i*i*i%5+1;
if(height+step<=n-i+1)height+=step;
elseheight=step+1;
num=guo[height];
for(j=height;j<=n-i;j++)guo[j]=guo[j+1];
}
printf("%d",num);
return0;}
Tip:
又是模拟。
。
。
我恨模拟。
。
。
好在这题比较简单。
。
。
4.贪婪的送礼者
对于一群要互送礼物的朋友,你要确定每个人送出的礼物比收到的多多少。
在这一个问题中,每个人都准备了一些钱来送礼物,而这些钱将会被平均分给那些将收到他的礼物的人。
然而,在任何一群朋友中,有些人将送出较多的礼物(可能是因为有较多的朋友),有些人有准备了较多的钱。
给出一群朋友,没有人的名字会长于14字符,给出每个人将花在送礼上的钱,和将收到他的礼物的人的列表,
请确定每个人收到的比送出的钱多的数目。
输入格式InputFormat
第1行:
人数NP,2<=NP<=10
第2到NP+1行:
这NP个在组里人的名字 一个名字一行
第NP+2到最后:
这里的NP段内容是这样组织的:
第一行是将会送出礼物人的名字。
第二行包含二个数字:
第一个是原有的钱的数目(在0到2000的范围里),第二个NGi是将收到这个送礼者礼物的人的个数如果NGi是非零的,在下面NGi行列出礼物的接受者的名字,一个名字一行。
输出格式
输出NP行
每行是一个的名字加上空格再加上收到的比送出的钱多的数目。
对于每一个人,他名字的打印顺序应和他在输入的2到NP+1行中输入的顺序相同。
所有的送礼的钱都是整数。
每个人把相同数目的钱给每位要送礼的朋友,而且尽可能多给,不能给出的钱被送礼者自己保留。
#include
#include
#include
inti,j,k,n,song,shou,qian;
charren[15];
structdata
{charname[15];
intmoney,in,out,renshu;
}stu[11];
intcmp(structdatap[],charq[])
{inti,j;
for(i=1;i<=n;i++)
{j=strcmp(p[i].name,q);
if(j==0)returni;
}
}
intmain()
{scanf("%d",&n);
for(i=1;i<=n;i++)
{scanf("%s",&stu[i].name);
stu[i].in=0;
stu[i].out=0;
stu[i].money=0;
}
for(i=1;i<=n;i++)
{scanf("%s",&ren);
song=cmp(stu,ren);
scanf("%d%d",&stu[song].money,&stu[song].renshu);
if(stu[song].renshu==0)continue;
qian=stu[song].money/stu[song].renshu;
for(j=1;j<=stu[song].renshu;j++)
{scanf("%s",ren);
shou=cmp(stu,ren);
stu[song].out+=qian;
stu[shou].in+=qian;
}
}
for(i=1;i<=n;i++)
printf("%s%d\n",stu[i].name,stu[i].in-stu[i].out);
system("pause");
return0;
}
Tip:
该死的模拟。
。
。
我最讨厌做模拟题了。
。
。
一点难度也没有做了3个小时才出来,第一次居然写了70多行,我靠。
。
。
还好一次AC,要WA了我就不做了。
。
。
这题还是pascal做好,不习惯用C的结构体,用pascal直接数组都能搞定,可恶的是C没有字符串变量。
。
。
4.吃糖果游戏
Matrix67和Shadow正在做一个小游戏。
桌子上放着两堆糖果,Matrix67和Shadow轮流对这些糖果进行操作。
在每一次操作中,操作者需要吃掉其中一堆糖果,并且把另一堆糖果分成两堆(可以不相等)留给对方操作。
游戏如此进行下去,糖果数会越来越少,最后必将出现这样一种情况:
某人吃掉一堆糖果后发现另一堆里只剩一块糖果不能再分了。
游戏规定此时该操作者吃掉最后这一块糖果从而取胜。
这个游戏是不公平的。
对于任意一种初始状态,总有一方有必胜策略。
所谓有必胜策略是指,无论对方如何操作,自己总有办法取胜。
Matrix67和Shadow将进行10次游戏,每一次游戏中总是Matrix67先进行操作。
Matrix67想知道每一次游戏中谁有必胜策略。
输入格式InputFormat
输入数据一共10行,每行有两个用空格隔开的正整数,表示一次游戏开始时桌子上两堆糖果分别有多少个。
对于50%的数据,这些正整数均不超过100;
对于70%的数据,这些正整数均不超过10000;
对于100%的数据,这些正整数均不超过10000位。
输出格式OutputFormat
输出十行字符串。
这些字符串只能是“Matrix67”或“Shadow”,它们表示对应的十行输入数据中有必胜策略的一方。
请注意大小写。
#include
#include
#include
intmain()
{inti;
charx[10001],y[10001],a,b;
for(i=0;i<10;i++)
{scanf("%s%s",x,y);
a=x[strlen(x)-1];
b=y[strlen(y)-1];
if(((a=='2')||(a=='3')||(a=='7')||(a=='8'))&&((b=='2')||(b=='3')||(b=='7')||(b=='8')))
printf("Shadow");
else
printf("Matrix67");
}
system("pause");
return0;
}
Tip:
当面临着糖果数为2或3的一堆时,你就输定了;枚举后发现发现,当面临糖果数为7或8的一堆时,你也输定了。
另外像这种数位上万的,一般只要考虑尾数就好了。
。
。
5.黑皮的蛋糕
为了庆祝黑皮的1006岁生日,也就是2006年01月01日。
校长为他在学校里举行一个名为{天造奇才}的大型庆祝活动。
邀请全校的师生及其家属们都参加。
考虑到当时人数相当庞大,黑皮的好友小佳佳特地为他从美国进口了个超级无敌大蛋糕1号。
供到场的所有人享用。
黑皮也考虑到人数太多,蛋糕又只有一个。
所以决定自己用在最少的刀数划出最多的蛋糕份数。
比如说:
开始是1个蛋糕,份数为1;黑皮一刀子划下去,刀数为1,份数就为2了;再一刀,刀数为2,份数为4;再一刀………………若干刀下去,份数就为n了。
他想知道你们是否也能划出来。
输入格式InputFormat
输入一个数,即为黑皮当时划的刀数n。
0<=n<=34567890;
输出格式OutputFormat
一个数,即为到场人数。
已知人数与黑皮划下来的份数相同。
#include
#include
intmain()
{doublen;
scanf("%lf",&n);
printf("%.0lf",(n+1)*n/2+1);
system("pause");
return0;
}
6.奖学金
某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。
期末,每个学生都有3门课的成绩:
语文、数学、英语。
先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。
任务:
先根据输入的3门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前5名学生的学号和总分。
注意,在前5名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。
例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:
学号、总分)是:
7279
5279这两行数据的含义是:
总分最高的两个同学的学号依次是7号、5号。
这两名同学的总分都是279(总分等于输入的语文、数学、英语三科成绩之和),但学号为7的学生语文成绩更高一些。
如果你的前两名的输出数据是:
5279
7279则按输出错误处理,不能得分。
输入格式InputFormat
输入包含n+1行:
第l行为一个正整数n,表示该校参加评选的学生人数。
第2到年n+l行,每行有3个用空格隔开的数字,每个数字都在0到100之间。
第j行的3个数字依次表示学号为j-1的学生的语文、数学、英语的成绩。
每个学生的学号按照输入顺序编号为1~n(恰好是输入数据的行号减1)。
所给的数据都是正确的,不必检验。
输出格式OutputFormat
输出共有5行,每行是两个用空格隔开的正整数,依次表示前5名学生的学号和总分。
#include
#include
intmain()
{inti,j,n,yu[301],x,y,sum[301]={0};
scanf("%d",&n);
for(i=1;i<=n;i++)
{scanf("%d%d%d",&yu[i],&x,&y);
sum[i]=yu[i]+x+y;
}
x=0;
for(i=1;i<=5;i++)
{for(j=1;j<=n;j++)
{if(sum[j]>sum[x]||sum[j]==sum[x]&&yu[j]>yu[x])
x=j;
}
printf("%d%d\n",x,sum[x]);
sum[x]=0;
yu[x]=0;
}
system("pause");
return0;
}
Tip:
很简单,不说了,就是模拟的时候思路要清晰,我一开始就混乱了。
。
。
7.盗窃-大海的奇迹
TheBlueWonder被OIBH悬空挂在大厅的天花板上,距地面有m米的高度。
大厅是
一个圆形的半球顶房间,直墙高度为n米。
大厅半径为r米。
基德可以在直墙上的,任意一点移动,但不能移动到半球顶上。
基德需要用一根细丝连上BlueWonder来走上去(好厉害啊,钢丝杂技)。
需要你帮他计算细丝的最短长度。
输入格式InputFormat
一行,三个实数m,n,r。
输出格式OutputFormat
一行一个实数min,表示细丝的最短长度。
你需要把这个数保留到3位小数。
#include
#include
#include
intmain()
{doublem,n,r,min;
scanf("%lf%lf%lf",&m,&n,&r);
if(n>=m)min=r;
elsemin=sqrt(pow(r,2)+pow(m-n,2));
printf("%.3lf",min);
system("pause");
return0;
}
Tip:
简单题,注意精度,要用double才行。
。
一开始用了float给WA了。
。
。
8.天平称量
有n个球,从外表上看不出差别,但有一个球比其他球重,其他N-1个球质量相等。
请问:
在地球上(MS废话),用天平最少称几次可以称出来?
输入格式InputFormat:
一个自然数N(0输出格式OutputFormat:
输出用天平最小的称量数m(m<30000)
#include
#include
#include
intmain()
{longn,m;
scanf("%d",&n);
m=ceil(log(n)/log(3));
printf("%d",m);
system("pause");
return0;
}
Tip:
天平称量问题,证明我不会。
。
。
天平称重,有两个托盘比较轻重,加上托盘外面,也就是每次称重有3个结果,就是ln3/ln2比特信息。
n个球要知道其中一个不同的球,如果知道那个不同重量的球是轻还是重,找出来的话那就是n个结果中的一种,就是有ln(n)/ln2比特信息,假设我们要称k次,根据信息理论:
k*ln3/ln2>=ln(n)/ln2,解得k>=ln(n)/ln3
学会2个函数:
floor(x)返回的是小于或等于x的最大整数。
ceil(x)返回的是大于x的最小整数。
另外还有一点是:
ln(x)在C中是log(x),lg(x)在C中是log10(x)
9.现代数学的著名证明之一是GeorgCantor证明了有理数是可枚举的。
他是用下面这一张表来证明这一命题的:
1/1 1/2 1/3 1/4 1/5…
2/1 2/2 2/3 2/4 …
3/1 3/2 3/3 …
4/1 4/2 …
5/1 …
…
我们以Z字形给上表的每一项编号。
第一项是1/1,然后是1/2,2/1,3/1,2/2,…
输入格式输入:
整数N(1≤N≤10000000)
输出格式输出:
表中的第N项
#include
#include
intmain()
{longi=0,n;
scanf("%ld",&n);
while(i{n-=i;
i++;
}
if(i%2==0)printf("%d/%d",n,i+1-n);
elseprintf("%d/%d",i+1-n,n);
system("pause");
return0;
}
Tip:
纯粹的数学问题,第K个斜行("/"方向)上每个分数的分子分母之和为K+1,因此先算出第N项所在的斜行K,然后看斜行是奇数项还是偶数项,进而算出具体分数值。
10.明明的随机数
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。
然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。
请你协助明明完成“去重”与“排序”的工作。
输入格式:
输入有2行,第1行为1个正整数,表示所生成的随机数的个数N
第2行有N个用空格隔开的正整数,为所产生的随机数。
输出格式:
输出也是2行,第1行为1个正整数M,表示不相同的随机数的个数。
第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
#include
#include
intmain()
{inti,j,n,sum=0,x[1001]={0};
scanf("%d",&n);
for(i=1;i<=n;i++)
{scanf("%d",&j);
if(x[j]==0)sum++;
x[j]=1;
}
printf("%d\n",sum);
for(i=1;i<=1000;i++)
if(x[i]==1)printf("%d",i);
system("pause");
return0;
}
Tip:
最简单的办法就是桶排序,这样进行一次筛选和排序就都出来了。
桶排序也叫基数排序。
如果我们有N个整数,范围从1到M(或从0到M-1),我们留置一个数组A,大小为M,并初始化为0。
于是该数组有M个单元(我们称之为桶),开始他们都是空的。
当数a被读入时,A[a]增1。
当所有的输入被读进时,扫描数组,打印出排好序的表。
这就是所谓的桶排序。
11.黑皮的正方形
一天黑皮不务正业出去耍,看见街上的地板是由很多小的正方形组成,顿时心里突发奇想想要总结一下到底有多少正方形。
。
。
。
于是乎,他狠下心数了数,终于翻山越岭知道了正方形的总边长为N,你的目的是找出在可以组成的每个至少边为1的正方形的个数。
(因为黑皮太笨了,无法找到)。
。
输入格式:
自然数(0<=n<=32767)
输出格式:
一个数,即正方形的总数
#include
#include
intmain()
{inti,n;
doublesum=0;
scanf("%ld",&n);
for(i=1;i<=n;i++)sum+=i*i;
printf("%.0lf",sum);
system("pause");
return0;
}
Tip:
拿笔在纸上写几个数就知道这是自然数的平方和了,用n*(n+1)*(2*n+1)/6公式可以很方便地求出结果,但是第一次我WA了,最后三个数没过,想到可能是long不够,准备换成longlong来算,可是中间试验的时候发现当n在10000左右的时候数据溢出了,换成double型也同样溢出。
。
。
考虑到这可能是n*(n+1)*(2*n+1)/6公式的问题。
。
。
换成循环,没问题,提交,AC。
。
。
12.连续自然数和
对一个给定的自然数M,求出所有的连续的自然数段(连续个数大于1),这些连续的自然数段中的全部数之和为M。
例子:
1998+1999+2000+2001+2002=10000,所以从1998到2002的一个自然数段为M=10000的一个解。
输入格式:
包含一个整数的单独一行给出M的值(10<=M<=2,000,000)
输出格式:
每行两个自然数,给出一个满足条件的连续自然数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。
#include
#include
intmain()
{longn,i,j;
scanf("%ld",&n);
for(i=1;i<=n/2;i++)
for(j=i+1;j<=n;j++)
{if((i+j)*(j-i+1)/2>n)break;
if((i+j)*(j-i+1)/2==n)
{printf("%ld%ld\n",i,j);
break;