ACM程序设计-赛题样例

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ACM程序设计-赛题样例
座位调整
题目描述:
百度办公区里到处摆放着各种各样的零食。

百度人力资源部的调研发现,员工如果可以在自己喜欢的美食旁边工作,工作效率会大大提高。

因此,百度决定进行一次员工座位的大调整。

调整的方法如下:
1 .首先将办公区按照各种零食的摆放分成 N 个不同的区域。

(例如:可乐区,饼干区,牛奶区等等)。

2 .每个员工对不同的零食区域有不同的喜好程度(喜好程度度的范围为 1 — 100 的整数,喜好程度越大表示该员工越希望被调整到相应
的零食区域)。

3 .由于每个零食区域可以容纳的员工数量有限,人力资源部希望找到一个最优的调整方案令到总的喜好程度最大。

数据输入:
第一行包含两个整数 N , M ,( 1<=N ,
M<=300 )。

分别表示 N 个区域和 M 个员工。

第二行是 N 个整数构成的数列 a ,其中 a[i] 表示第 i 个区域可以容纳的员工数,
(1<=a[i]<=M , a[1]+a[2]+..+a[N]=M) 。

紧接着是一个 M*N 的矩阵 P , P ( i , j )表示第 i 个员工对第 j 个区域的喜好度。

答案输出:
对于每个测试数据,输出可以达到的最大的喜好程度。

输入样例
3 3
1 1 1
100 50 25
100 50 25
100 50 25
输出样例
175
#include<stdio.h>
void main()
{
int n,m,l=0,i,j,s,t,sum=0;
int a[100],p[100][100],b[100],c[100];
for(i=0;i<100;i++)
{
a[i]=0,c[i]=0,b[i]=0;
for(j=0;j<100;j++)
p[i][j]=0;
}
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d ",&a[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&p[i][j]);
}
}
i=0;
frist:if(i>=m)goto finish;
if(l>0)
{
for(s=0;s<l;s++)
{
t=c[s];
for(j=0;j<m;j++)
{
p[t][j]=0;
}
}
}
for(s=0;s<m;s++)
{
b[s]=0;
}
for(s=0;s<n;s++)
{
b[s]=p[s][i];
}
for(s=0;s<n-1;s++)
{
for(j=0;j<n-1-s;j++)
{
if(b[j]<b[j+1])
{
t=b[j];
b[j]=b[j+1]; b[j+1]=t;
}
}
}
// printf("%d\t",b[0]); // test++;
for(s=0;s<a[i];s++)
{
sum=sum+b[s];
}
s=0;
sec:if(s>=a[i])
{
i++;
goto frist;
}
for(t=0;t<n;t++)
{
if(b[s]==p[t][i])
{
c[l]=t;l++;break;
else continue;
}
s++;
goto sec;
finish:
// printf("\n");
printf("最大的喜好程度为:%d\n",sum);
// printf("%d",test);
}
#include<stdio.h>
#include<stdlib.h>
void main()
{
int s,t,u,v,w,x,y,z,sum=0,a[20],b[20][20],c[20],d[20],sumx[80],*p=sumx,max; scanf("%d%d",&x,&y);
for(z=0;z<x;z++)
{
scanf("%d",&a[z]);
}
for(z=0;z<y;z++)
{
c[z]=z;
d[z]=z;
}
for(w=0;w<y;w++)
{
for(z=0;z<x;z++)
{
scanf("%d",&b[w][z]);
}
}
sum=0;
for(z=0;z<y;z++)
{
sum+=b[0][z];
for(w=z;w<y-1;w++)
d[w]=d[w+1];
}
for(w=0;w<y-1;w++)
{
s=d[w];
sum+=b[1][s];
for(v=w;v<y-2;v++)
{
d[v]=d[v+1];
}
for(u=0;u<y-2;u++)
{
s=d[u];
sum+=b[1][s];
for(t=u;t<y-3;t++)
{
d[u]=d[u+1];
}
for(t=0;t<y-3;t++)
{
s=d[t];
sum+=b[2][s];
for(z=0;z<y;z++)
{
d[20]=c[20];
}
}
*p=sum;
sum=0;
p++;
}
}
}
t=1;
max=sumx[0];
while(sumx[t])
{
if(sumx[t]>max)
max=sumx[t];
t++;
}
printf("%d\n",max);
}
#include<stdio.h>
#include<malloc.h>
int main(int argc,char** argv)
{
int N,M,*a,**p,*temp,i,j,k,max=0;;
printf("Please input area and staff num:");
scanf("%d %d",&N,&M);
a=(int*)malloc(sizeof(int)*N);
printf("\nPlease input staff num of each area:");
for(i=0;i<N;i++)
scanf("%d",&a[i]);
p=(int**)malloc(sizeof(int)*N);
printf("\nPlease input like:");
for(i=0;i<M;i++)
p[i]=(int*)malloc(sizeof(int)*M);
for(i=0;i<M;i++)
for(j=0;j<N;j++)
scanf("%d",&p[i][j]);
temp=(int*)malloc(sizeof(int)*M);
for(i=0;i<N;i++)
{
if(i<N-1){
for(j=0;j<M;j++)
{
k=i+1;
temp[j]=0;
while(k<N){
temp[j]+=p[j][i]-p[j][k];
k++;
}
}
int temp1,temp2;
while(a[i]){
temp1=-101;
temp2=0;
for(j=0;j<M;j++)
{
if(temp[j]>temp1)
{
temp1=temp[j];
temp2=j;
}
}
max+=p[temp2][i];
printf("%d %d %d\n",p[temp2][i],temp2,i);
for(int m=0;m<N;m++)
p[temp2][m]=-101;
printf("\n");
for(int q=0;q<M;q++)
{for(int w=0;w<N;w++)
{
printf(" %d ",p[q][w]);
}
printf("\n");
}
temp[temp2]=-101;
a[i]--;
}
}
else
{
int temp3,temp4;
while(a[i])
{
temp3=-101;
temp4=0;
for(j=0;j<M;j++)
{
if(p[j][i]>temp3)
{
temp3=p[j][i];
temp4=j;
}
}
max+=p[temp4][i];
printf("%d %d %d\n",p[temp4][i],temp4,i);
for(int m=0;m<N;m++)
p[temp4][m]=-101;
printf("\n");
for(int q=0;q<M;q++)
{for(int w=0;w<N;w++)
{
printf(" %d ",p[q][w]);
}
printf("\n");
}
temp[temp4]=-101;
a[i]--;
}
}
}
printf("Max=%d\n",max);
return0;//Your program should return 0 on normal termination.
}
蝈蝈式的记分
内容描述:
蝈蝈小朋友刚刚学会了 0-9 这十个数字 , 也
跟爸爸妈妈来参加百度每周进行的羽毛球活动。

但是他还没有球拍高,于是大人们叫他记录分数。

聪明的蝈蝈发现只要记录连续得分的情况就可以了,比如用“ 3 2 4 ”可以表示一方在这一局中连得三分后,输了两分,接着又连得到四分。

可是,后来大人们发现蝈蝈只会用 0-9 这十个数字,所以当比赛选手得分超过 9 的时候,他会用一个 X 来表示 10 完成记分。

但问题是,当记录为“ X 3 5 ”的时候,蝈蝈自己也记不起来是一方连续得到十三分后,再输五分;还是先赢十分输三分再赢五分。

因为百度内部就要开始进行羽毛球联赛了,要先摸清大家的实力才好分组比赛呢~于是,大人们想知道以前每局的比分是怎样的,以及谁获得了胜利。

要是遇到了根据比赛记录无法确认比赛进程的情况,也要输出相应的提示哦。

需要帮蝈蝈进一步说明的是,比赛是五局三胜的,每局先获得二十一分的为胜,但是胜方必须领先对手两分或以上,否则必须继续比赛直到一方超出对手两分为止,比分多的一方获胜。

任何一方先获得三局的胜利后就获得胜利,比赛也相应的结束。

而且蝈蝈保证是完整的无多余信息的记录了比赛。

输入数据:
以 point.in 为输入文件,文件中首行只有一个整数 M ,表示蝈蝈记录了多少场比赛的分数。

每场比赛用两行记录,第一行是一个整数
N(N<=1000) 表示当前这个记录中有多少个字符,第二行就是具体的 N 个字符表示记录的分数。

输出数据:
相应的内容将输出到 point.out 文件中,对应每一个分数记录,输出相应的每局分数,每局分
数都使用两个整数表示,表示两个选手的得分,中间用 ":" 分隔开;每组分数记录间使用一个空行分隔开。

如果相应的比赛结果无法预测的时候,以” Unknown “一个单词独占一行表示。

输入和输出结果数据样例:
输入样例
3
23
9 7 3 6 2 4 7 8 3 2 7 9 X 2 2 1 2 1 X 1 X 1 1
25
9 3 8 5 4 8 3 9 8 4 X X X X 2 X X X X 2 8 4 9 2 4
43
7 7 7 7 7 3 4 5 6 7 6 5 4 2 1 3 5 7 9 7 5 3 1 3 0 9 9 3 9 3 2 1 1 1 5 1 5 1 5 1 5 5 1
输出样例
21:17
24:22
21:3
Unknown
21:14
20:22
21:23
21:16
21:9
足球比赛
吉林一中将举办一年一度的足球比赛。

Andy的班级即将面临一组强队,就是去年的冠军队。

Andy在比赛之前做了充分的准备,搜集了许多关于这支队伍的信息。

在这支队伍中有N-1个队员,通过过去比赛记录来看,他们总是在某些固定的队员之间传球。

我们把对方的守门员编号为1号,我们的球门编号为N号,其他的为对方球员。

资料里给出若干个整数对(ai,bi),表示球会从ai传到bi,如果ai==1,代表球从对方守门员开出,如果bi==N,代表球攻入我方大门。

其他情况均为对方队友间的传球配合。

每组传球,还会给出一个实数pi,表示对方传球成功的概率,我方成功防守的概率就是1-pi。

我们会选择一些对方的传球路线做重点防御,使得不会出现某条从对方守门员到我方大门路径
完全没有防守。

假设我们选取的防御集合为S,我们定义了估价函数F(S)表示该种防守的可靠值
现在你需要计算这个可靠值最大值。

输入
输入包含多组测试数据。

数据的第一行包含两个整数N,M (1<= N <= 100, 1<= M <= 400), 接下来M行,每行包含三个数字ai bi Pi (1 <= ai, bi <= N , 0 <= Pi <= 1 ).
输入文件结束于 N = M = 0.
输出
对于每组数据,如果最大值为0,输出“The opponent is too strong!”如果最大值为1,输出“The opponent is too week!”,否则输出这个最大值,保留6位小数。

样例输入
4 4
1 2 0.5
2 4 0.6
2 3 0.5
3 4 0.8
4 4
1 2 1.0
2 3 1.0
3 4 1.0
2 4 1.0
4 4
1 2 0
2 3 1.0
3 4 1.0
2 4 1.0
0 0
样例输出
0.500000
The opponent is too strong! The opponent is too week!
提示
对于第一组样例数据,我们可以选择第一条路线做重点防御,此时 F 为 ( (1-0.5) ^ 1 ) == 0.5。

如果我们选择第三条和第四条路线做重点防御,此时F为 ( (1-0.6) * (1-0.8) ) ^ (1/2) == 0.282843。

只选择第三条路线是不合法的,对方可以通过1,2,4将球轻松送入我方大门。

#include<stdio.h>
#include<malloc.h>
float odds_of_lines=1.0;
float odds_of_total=0.0;
struct way
{
int start;
int end;
float odds;
};
struct way stack[10];
int ps=0;
void push(struct way a)
{
stack[ps]=a;
ps++;
}
void pop()
{
ps--;
}
void seek(struct way *ways,int first,int goal,int lines)
{
int i=0;
for(;i<=lines;i++)
{
if(i!=lines)
{
if(ways[i].start==first)
{
push(ways[i]);
if(stack[ps-1].end==goal)
{
int i=0;
for(;i<ps;i++)
{
odds_of_lines*=stack[i].odds;
}
odds_of_total+=odds_of_lines;
odds_of_lines=1.0;
pop();
}
else
{
seek(ways,stack[ps-1].end,goal,lines);
}
}
}
else if(i==lines)
{
}
}
}
int main()
{
int goal;
int lines;
scanf("%d%d",&goal,&lines);
getchar();
struct way *ways=(struct way*)malloc(sizeof(struct way)*lines);
int i;
for(i=0;i<4;i++)
{
scanf("%d%d%f",&ways[i].start,&ways[i].end,&ways[i].odds);
getchar();
}
seek(ways,1,4,4);
if(odds_of_total>=1) printf("The opponent is too strong!\n");
else if(odds_of_total<=0) printf("The opponent is too week!\n");
else printf("%.6f\n",odds_of_total);
return0;
}
说明:测试的时候是分组输入的,例如测试题目上给定的第一组数据。

输入
44
120.5
240.6
230.5
340.8
可以测试第一组,然后程序会结束,接着可以测试第二组,就是说输入:
44
121.0
231.0
341.0
241.0
以此类推。

平方数
给出包含M个数字的列表,和列表中所有数字的所有质因数。

求出最长的子列表,使得子列表中所有数字的乘积是一个完全平方数。

输入
输入文件包含多组测试数据。

第一行包含两个整数N , M ( 1 <= N <= 30 , 1 <= M <= 30000 ). N 是质因数的个数。

接下来一行有N个整数,给出所有的质因数。

然后一行包含M个整数,给出列表。

输入文件结束于N = M = 0.
输出
对于每组数据,输出最长子列表的两个位置坐标l r。

l是该子列表在列表中的起始位置,r是结束位置。

如果多种情况都满足子列表长度最大,输出l最小的一个。

如果不存在这样的子列表输出“None”。

样例输入
3 4
2 3 5
4 9 2
5 6
3 4
2 3 5
6 6 3 3
0 0
样例输出
1 3
1 4
#include<stdio.h>
int begin=0,end=0;
int judge(int m)//判断m是否是完全平方数
{
int i=2;
int count;
while(m!=1)
{
count=0;
if(m<i)
return0;
while(m%i==0)
{
m/=i;
count++;
}
if(count%2)
return0;
i++;
}
return1;
}
void operate(int*a,int n,int m) {
int x,y;
int i;
int total=1;
for(i=m;i<n;i++)
total*=a[i];
if(judge(total))
{
x=m;
y=n-1;
if(n-1-m>end-begin)
{
begin=x+1;
end=y+1;
}
return;
}
else
{
operate(a,n-1,m);
}
}
void main()
{
int n,i;
int a[100];
printf("输入数组长度n:");
scanf("%d",&n);
printf("输入数组元素:");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
operate(a,n,i);
printf("%d %d",begin,end);
}
技能树
Problem
玩过Diablo的人对技能树一定是很熟悉的。

一颗技能树的每个结点都是一项技能,要学会这项技能则需要耗费一定的技能点数。

只有学会了某一项技能以后,才能继续学习它的后继技能。

每项技能又有着不同的级别,级别越高效果越好,而技能的升级也是
需要耗费技能点数的。

有个玩家积攒了一定的技能点数,他想尽可能地利用这些技能点数来达到最好的效果。

因此他给所有的级别都打上了分,他认为
效果越好的分数也越高。

现在他要你帮忙寻找一个分配技能点数的方案,使得分数总和最高。

Input
该题有多组测试数据。

每组测试数据第一行是一个整数n(1<=n<=20),表示所有不同技能的总数。

接下来依次给出n个不同技能的详细情况。

每个技能描述包括5行。

第一行是该技能的名称。

第2行是该技能在技能树中父技能的名称,名称为None则表示该技能不需要任何的先修技能便能学习。

第3行是一个整数L(1<=L<=20),表示这项技能所能拥有的最高级别。

第4行共有L个整数,其中第I个整数表示从地I-1级升到第I级所需要的技能点数(0级表示没有学习过)。

第5行包括L个整数,其中第I个整数表示从第I-1级升级到第I级的效果评分,分数不超过20。

在技能描述之后,共有两行,第1行是一个整数P,表示目前所拥有的技能点数。

接下来1行是N个整数,依次表示角色当前习得
的技能级别,0表示还未学习。

这里不会出现非法情况。

Output
每组测试数据只需输出最佳分配方案所得的分数总和。

Sample Input
3
Freezing Arrow
Ice Arrow
3
3 3 3
15 4 6
Ice Arrow
Cold Arrow
2
4 3
10 17
Cold Arrow
None
3
3 3 2
15 5 2
10
0 0 1
Sample Output
42
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#define CHAR_LEN 20
#define INT_LEN 10
typedef struct SkillTree{
char*NameSon;
char*NameFather;
int*NeedPoint;
int*Score;
int MaxLeve;
struct SkillTree*NEXT;
}Skill,*SkillTree;
int CreatSkillTree(SkillTree*T)
{
int i,j,num;
SkillTree Au,Bu;
(*T)=(SkillTree)malloc(sizeof(Skill));
(*T)->NEXT=NULL;
Au=*T;
scanf("%d",&num);
for(i=0;i<num;i++)
{
Bu=(SkillTree)malloc(sizeof(Skill));
Bu->NEXT=NULL;
Bu->NameSon=(char*)malloc(sizeof(char)*CHAR_LEN);
Bu->NameFather=(char*)malloc(sizeof(char)*CHAR_LEN);
Bu->NeedPoint=(int*)malloc(sizeof(int)*INT_LEN);
Bu->Score=(int*)malloc(sizeof(int)*INT_LEN);
getchar();
gets(Bu->NameSon);
gets(Bu->NameFather);
scanf("%d",&Bu->MaxLeve);
for(j=0;j<Bu->MaxLeve;j++) scanf("%d",Bu->NeedPoint+j);
for(j=0;j<Bu->MaxLeve;j++) scanf("%d",Bu->Score+j);
Au->NEXT=Bu;
Au=Bu;
}
return num;
}
int LocatFath(SkillTree*T,char*Name)
{
int Lct;
SkillTree Au;
Au=(*T)->NEXT;Lct=1;
while(Au)
{
if(strcmp(Au->NameSon,Name))
{
Au=Au->NEXT;
Lct++;
}
else return Lct;
}
return-1;
}
SkillTree GradFath(SkillTree*T,int nPos)
{
int Lc;
SkillTree Au;
Au=(*T)->NEXT;Lc=1;
while(Au&&(Lc<nPos))
{
Au=Au->NEXT;
Lc++;
}
if(Lc==nPos&&Au)
{
return Au;
}
return NULL;
}
int MaxScore(SkillTree*T,int Remain,int*Grade)
{
int i,MaxS,Sum=0,LS,LF,Td;
SkillTree Au;
while(Remain>0)
{
MaxS=-1;
Au=(*T)->NEXT;LS=1;
while(Au)
{
LF=LocatFath(T,Au->NameFather);
for(i=*(Grade+LS-1)+1;i<=Au->MaxLeve;i++)
{
if((MaxS<*(Au->Score+i-1))&&(Remain>=*(Au->NeedPoint+i-1)))
{
if(i==1)
{
if((strcmp(Au->NameFather,"None")&&LF!=-1&&*(Grade+LF-1 )>0)||(!strcmp(Au->NameFather,"None")))
{
MaxS=*(Au->Score+i-1);Td=LS;
}
else{
break;
}
}
else if((i>1)&&(*(Grade+LS-1)==i-1))
{
MaxS=*(Au->Score+i-1);Td=LS;
}
else{
break;
}
}
else{
break;
}
}
Au=Au->NEXT;LS++;
}
if(MaxS!=-1)
{
(*(Grade+Td-1))++;
Au=GradFath(T,Td);
Remain-=*(Au->NeedPoint+*(Grade+Td-1)-1);
Sum+=MaxS;
}
else{
break;
}
}
return Sum;
}
main()
{
int i,R,N,MaxP,*G;
SkillTree t;
N=CreatSkillTree(&t);
G=(int*)malloc(sizeof(int)*N);
scanf("%d",&R);
for(i=0;i<N;i++) scanf("%d",G+i);
MaxP=MaxScore(&t,R,G);
printf("%d",MaxP);
getch();
}
嗅探器
Problem
某军搞信息对抗实战演习.红军成功地侵入了蓝军的内部网络.蓝军共有两个信息中心.红军计划在某台中间服务器上安装一个嗅探
器,从而能够侦听到两个信息中心互相交换的所有信息.但是蓝军的网络相当的庞大,数据包从一个信息中心传到另一个信息中心可
以不止有一条通路.现在需要你尽快地解决这个问题.应该把嗅探器安装在哪个中间服务器上才能保证所有的数据包都能被捕获?
Input
该题含有多组测试数据。

第一行一个整数n(1<=n<=100),表示蓝军网络中服务器的数目.
接下来若干行是对蓝军网络的拓扑结构描述. 每行是两个整数i,j表示编号为I和编号为j的两台服务器间存在连接(显然连接是双向的).服务器的编号从1开始.描述一两个0结束.
再接下来一行是两个整数a,b分别表示两个中心服务器的编号.
Output
输出编号。

如果有多个解输出编号最小的一个.如果找不到任何解,输出”No solution”.
Sample Input
5
2 1
2 5
1 4
5 3
2 3
5 1
0 0
4 2
Sample Output
1
陶陶摘苹果
【问题描述】
陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。

苹果成熟的时候,陶陶就会跑去摘苹果。

陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。

现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。

假设她碰到苹果,苹果就会掉下来。

【输入文件】
输入文件apple.in包括两行数据。

第一行包含10个100到200之间(包括100和200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。

第二行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。

【输出文件】
输出文件apple.out包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。

【样例输入】
100 200 150 140 129 134 167 198 200 111 110
【样例输出】
5
#include<stdio.h>
int main()
{
int high[10],height,counter=0;
scanf("%d%d%d%d%d%d%d%d%d%d",&high[0],&high[1],&high[2],&high[3],&high[4],& high[5],&high[6],&high[7],&high[8],&high[9]);
scanf("%d",&height);
for(int i=0;i<10;i++)
if(height+30>=high[i])
counter++;
printf("%d",counter);
}
#include<stdio.h>
int main()
{
FILE *fp;
int a[10]={0},i,h,n=0;
fp=fopen("apple.in.txt","r");
if(fp==NULL)
{
printf("文件打开失败\n");
exit(0);
}
for(i=0;i<10;i++)
{
fscanf(fp,"%d",&a[i]);
}
fscanf(fp,"%d",&h);
h=h+30;
for(i=0;i<10;i++)
{
if(h>=a[i])
{
n++;
}
}
printf("%d\n",n);
fclose(fp);
}
#include<stdio.h>
int main(void)
{
int a[11]=0,i=0,j,n=0;
for(i=1;i<=10;i++)
scanf("%d",&a[i]);
scanf("%d",&j);
j=j+30;
for(i=1;i<=10;i++)
if(j>=a[i])
n++;
printf("%d\n",n);
}
幻方矩阵
Problem description
幻方是一种很有意思的数字矩阵,在很早著名的九宫八卦阵就与幻方有关。

幻方的定义为:
1 到 N*N 的整数填入N*N的方格中,每行和每列以及对角线的数字之和必须是相等的。

你作为八卦公司的顶级程序员,现在需要你解决一个问题,将任意奇数阶的幻方找出来。

Input
输入包括多个测试集,每行为一个正奇数N(1 <= N < 1000),0作为输入的结束且不需要处理。

Output
对于输入的每一个N,输出一个它所对应的N
阶幻方,如果存在多个,任意一个即可。

每个幻方为N*N的矩阵,
对于每个幻方,每行输出幻方的一行,每行中的数字之间用一个或多个空格分开。

不同的幻方之间用一个空行分开。

Sample Input
1
3
Sample Output
1
4 9 2
3 5 7
8 1 6
//只能是奇数阶的,算法看以参照下面
#include<stdio.h>
#define MAX 20
void main()
{
int i,j,k,n;
int a[MAX][MAX]={0};
printf("请输入魔法矩阵的行数(或列数)\n"); do{
scanf("%d",&n);
if(n%2==0)
printf("\n请输入一个奇数(<20)\n"); }while(n%2==0);
i=0;
j=n/2;
a[i][j]=1;
for(k=2;k<=n*n;k++)
{
if(a[(i-1+n)%n][(j+1)%n]==0)
{
i=(i-1+n)%n;
j=(j+1)%n;
}
else
i=(i+1)%n;
a[i][j]=k;
}
printf("\n下面是%d维魔方的展示:\n",n);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%10d",a[i][j]);
putchar('\n');
}
}
#include<stdio.h>
int main()
{
while(1){
int n;
int x,y;
int cube[1000][1000];
scanf("%d",&n);
if(n==0){
break;
}
for(x=0;x<n;x++){
for(y=0;y<n;y++){
cube[x][y]=0;
}
}
int a=1;
x=0;
y=(n+1)/2-1;
while(a!=n*n+1){
cube[x][y]=a;
if(x==0&& y==n-1){
x=x+1;
a=a+1;
}
else if(x==0&& y!=n-1){
x=n-1;
y=y+1;
a=a+1;
}
else if(x!=0&& y==n-1){
x=x-1;
y=0;
a=a+1;
}
else if(cube[x-1][y+1]==0){ x=x-1;
y=y+1;
a=a+1;
}
else{
x=x+1;
a=a+1;
}
}
for(x=0;x<n;x++){
for(y=0;y<n;y++){
printf("%d ",cube[x][y]);
}
printf("\n");
}
}
return0;
}
环城汽车赛
环城汽车赛
XYZ城要举行一场汽车赛,因为XYZ城的巿长是个怪人,所以这次汽车赛有特殊的规则。

在这次比赛的环形赛道上设有N个汽车加油站。

选手可以选择任意一个作为起点。

比赛开始时每辆汽车油箱里都没有油。

在到达第i个加油站时了,汽车可以有那加Oi升的油。

(我们设一升油可以开一km,并和速度无关)。

所以加油站的油加起来正好可以开完全程。

最快开完全程(逆时针)的选手将获得第一名。

当然,所有的选手都想夺冠,所以他们都想先知道从哪些加油站开始可以跑完全程。

这个任务就交给你了!
Input
第一行为一整数T,表示有T组测试数据。

每组测试数据二行。

每组测试数据的第一行是一个数字N(4<=N<100000)
第二行是用空格分开的2N个整数,第一个数是第一个加油站可以提供的油O1升,第二个数是第一站到第二站距离D1km(N个站是逆时针排列的),……,最后一个是第N站个第一站的距离DNkm。

(Oi,Di<=100000)
Output
对于每一组测试数据你输出一行两个数第一个数是一共有多少站可以那开始完成全程,第二个数是编号最小的可以完成全程的加油站的编号(如果第一个数是0这里输出-1)。

Sample Input
2
4
1 2 3 2 5 6 7 6
8
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
Sample Output
2 2
8 1
#include<stdio.h>
struct station{
float dis;
float oil;
};
bool CanWin(int N,station*Sta,station* pS) {
float Dis=Sta->dis,Oil=Sta->oil;
for(int i=0;i<N-1;i++)
{
Sta++;
if(Sta->dis==0&&Sta->oil==0)
Sta=pS;
Dis+=Sta->dis;
Oil+=Sta->oil;
if(Oil<Dis)
return0;
}
return1;
}
void Zero(station*Sta,int N)
{
for(int i=0;i<N+1;i++)
{
Sta->dis=0;
Sta->oil=0;
Sta++;
}
}
int main()
{
int T;
scanf("%d",&T);
for(int i=0;i<T;i++)
{
station Station[10000];
int N;
station* pS=Station;
scanf("%d",&N);
Zero(pS,N);
for(int j=0;j<N;j++)
{
scanf("%f%f",&Station[j].oil,&Station[j].dis);
}
int n=0,m=-1;
for(int j=0;j<N;j++)
{
if(CanWin(N,&Station[j],pS))
{
n++;
if(n==1)
m=j+1;
}
}
printf("%d %d\n",n,m);
}
return0;
}
字符串的距离
Problem
设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为“abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的扩
展串,这里“□”代表空格字符。

如果A1是字符串A的扩展串,B1是字符串B的扩展串,A1与B1具有相同的长度,那么我们定义字符串A1与B1的距离为相应位置上的字符的距离总和,而两个非空格字符的距离定义为它们的ASCII 码的差的绝对值,而空格字符与其它任意字符之间的距离为已知的定值K,空格字符与空格字符的距离为O。

在字符串A、B的所有扩展串中,必定存在两个等长的扩展串A1、B1,使得A1与B1之间的距离达到最小,我们将这一距离定义为字符串A、B的距离。

请你写一个程序,求出字符串A、B的距离。

Input
有多组数据,每一组数据第一行为字符串A,第二行为字符串B,A、B均由小写字母组成且长度均不超过2000,第三行为一个整数K,1≤K≤100,表示空格与其它字符的距离。

Output
每组数据一行包含一个整数,表示要求的字符串A、B的距离。

Sample Input
cmc
snmn
2
Sample Output
10
Feli的生日礼物
Problem
Felicia的生日是11月1日(和Kitty是同一天生的哦)。

于是Feli请来Kitty一起过生日。

Kitty带来了最新款的“Kitty猫”玩具准备送给Feli,不过她说,这份礼物可不是白送的。

Feli要帮她一个忙,才能够得到心仪已久的玩具。

Kitty说,“Kitty猫”玩具已经卖出了
n!个,n<=10^100 *_*,Kitty想知道确切的数字,而不是无聊的“一个数加个感叹号”。

Feli 听了大吃一惊。

要知道,算出n!是一个无比艰
巨的任务。

Feli告诉Kitty,就算Feli算出n!,Kitty也看不下去,因为当n=20时,计算机的长整型已经存不下了(Kitty只能接受1-9之间的数字)。

于是Kitty说,你只要告诉我n!最后一位非0的数就可以了。

Feli想了想,立刻动手写了个程序算出了正确的答案。

现在,请你也试试看!注意哦,AC的男生将会得到一个“Hello Kitty”计算器(可编程,CPU 1THz,Mem 1TMB),AC的女生将会得到一个仿真“Hello Kitty”宠物(善解人意,无须喂养,智商1101,附带写情书功能)。

Input
每行一个n,直到输入数据结束
Output
对应输入的n,每行输出一个答案
Sample Input
1101
Sample Output
8
#include<stdio.h>
#include<string.h>
int a[102]={0},b[102]={0};
void div2()
{int i;
for(i=0;i<=100;i++)
b[i]=(10*b[i+1]+b[i])/2%10;
}
void div5()
{int i;
for(i=0;i<=100;i++)
b[i]=(10*b[i+1]+b[i])/5%10;
}
void div10()
{int i;
for(i=0;i<=100;i++)
b[i]=b[i+1];
}
void sub1()
{int i;
a[0]--;
for(i=0;i<=100;i++)
if(a[i]==-1){a[i]=0;a[i+1]--;}
else break;
}
int check()
{int i;
for(i=0;i<=100;i++)
if(a[i]!=0)return1;
return0;
}
void main ()
{
int i;
int l,r=1,t=0;
char c[101]="";
scanf ("%s",c);
l=strlen(c)-1;
for(i=0;i<=l;i++)
a[i]=c[l-i]-'0';
while(check())
{for(i=0;i<=101;i++) b[i]=a[i];
while(b[0]==0) div10();
while(b[0]==5){div5();t++;}
if(t>0&&b[0]%2==0){div2();t--;}
r*=b[0];
r%=10;
sub1();
}
printf ("%d\n",r);
}
#include"stdio.h"
int fun(int last,int n)
{
int temp;
if(1==n)
return last%10;
else
{
temp =last*n;
while(0==temp%10)
temp = temp/10;
last= temp%100;
fun(last,n-1);
}
}
main()
{
int n=1,num,last=1;
while(n!=-1)
{
scanf("%d",&n);
num=fun(last,n);
printf("the last num of n! is:%d\n",num);
}
}
#include<stdio.h>
int clean(int x)
{
if(x%10!=0)
{
x=x%10;
return x;
}
else
{
x=x/10;
clean(x);
}
}
main()
{
int a,i,m=1;
scanf("%d",&a);
for(i=2;i<=a;i++)
{
m=m*i;
m=clean(m);
}
printf("%ld",m);
}
整数划分问题
整数划分是一个经典的问题。

希望这道题会对你的组合数学的解题能力有所帮助。

Input
每组输入是两个整数n和k。

(1 <= n <= 50, 1 <= k <= n)
Output
对于每组输入,请输出六行。

第一行:将n划分成若干正整数之和的划分数。

第二行:将n划分成k个正整数之和的划分数。

第三行:将n划分成最大数不超过k的划分数。

第四行:将n划分成若干奇正整数之和的划分数。

第五行:将n划分成若干不同整数之和的划分数。

第六行:打印一个空行。

Sample Input
5 2
Sample Output
7
2
3
3
3
#include"stdio.h"
int sum[5];
int num[1000];
int num_max=0;
void f(int n,int k)
{
if(n==0)
{
int flag=0,kmax=0,flag1=0;
for(int i=0;i<num_max ;i++)
{
if(num[i]<num[i+1]){num_max--;return;} }
for(int i=0;i<num_max ;i++)
{
if(num[i]>kmax) kmax=num[i];
if(num[i]%2==0) flag=1;
for(int j=i+1;j<num_max;j++)
if(num[i]==num[j]) flag1=1;
}
sum[0]++;
if(num_max==k) sum[1]++;
if(kmax<=k) sum[2]++;
if(!flag) sum[3]++;
if(!flag) sum[4]++;
}
if(n>0)
{
for(int i=1;i<=n;i++)
{
num[num_max++]=i;
f(n-i,k);
}
}
num_max--;
}
int _tmain(int argc, _TCHAR* argv[])
{
int n,k;
scanf("%d %d",&n,&k);
f(n,k);
for(int i=0;i<5;i++)
printf("%d\n",sum[i]);
return0;
}
破解平方数
Problem
给出m个数b1, b2,..., bm,每个数的素数因子都在前t个素数之内,任务是寻找这m个数的非空子集的个数x,使得每个子集的乘积都是一个完全平方数。

例如t=3,则前3个素数为2, 3, 5。

m=4,这4个数为9, 20, 500, 3,每个数的素因子都是在前3个素数内,则有x=3个非空子集合{9}, {20, 500}, {9, 20, 500},满足每个集合内的数的乘积是一个完全平方数,输出这样的集合的个数。

Input
每组测试数据的第一行为两个正整数t, m(1 ≤t ≤ 100, 1 ≤ m ≤ 100) 第二行为m个数, 1 <= bi <= 109 处理至文件结束
Output
每行输出一个整数x,对应每组测试数据
Sample Input
3 4
9 20 500 3
Sample Output
3
#include<stdio.h>
#include<math.h>。

相关文档
最新文档