OpenJudge算法设计与分析习题解答Word文档下载推荐.docx
- 文档编号:17912689
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:37
- 大小:37.05KB
OpenJudge算法设计与分析习题解答Word文档下载推荐.docx
《OpenJudge算法设计与分析习题解答Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《OpenJudge算法设计与分析习题解答Word文档下载推荐.docx(37页珍藏版)》请在冰豆网上搜索。
=A;
k++){
if(i*5+j*2+k*1==n){
printf("
%03d%12d%12d%12d\n"
t,k,j,i);
t++;
}
}
}
}
getchar();
return0;
}
2、比赛排名
5名运动员参加100米赛跑,各自对比赛结果进行了预测:
A说:
E是第1名。
B说:
我是第2名。
C说:
A肯定垫底。
D说:
C肯定拿不了第1名。
E说:
D应该是第1名。
比赛结束后发现,只有获第1名和第2名的选手猜对了,E不是第2名和第3名,没有出现名次并列的情况。
请编程判断5位选手各是第几名。
无
输出要求:
按ABCDE的顺序输出5行,其中第1行是A的名次,第2行是B的名次,
第3行是C的名次,第4行是D的名次,第5行是E的名次。
intmain()
{
printf("
5\n"
);
2\n"
1\n"
3\n"
4\n"
}
3、鸡兔同笼
一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外)。
已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。
一行,一个正整数a(a<
32768)。
一行,包含两个正整数,第一个是最少的动物数,第二个是最多的动物数,两个正整数用一个空格分开。
如果没有满足要求的答案,则输出两个0,中间用一个空格分开。
20
510
#include<
intn;
scanf("
if(n%4==0)
printf("
%d%d"
n/4,n/2);
elseif(n%4!
=0&
&
n%2==0)
n/4+1,n/2);
else
00"
return0;
4、谁是你的潜在朋友
“臭味相投”——这是我们描述朋友时喜欢用的词汇。
两个人是朋友通常意味着他们存在着许多共同的兴趣。
然而作为一个宅男,你发现自己与他人相互了解的机会并不太多。
幸运的是,你意外得到了一份北大图书馆的图书借阅记录,于是你挑灯熬夜地编程,想从中发现潜在的朋友。
首先你对借阅记录进行了一番整理,把N个读者依次编号为1,2,…,N,把M本书依次编号为1,2,…,M。
同时,按照“臭味相投”的原则,和你喜欢读同一本书的人,就是你的潜在朋友。
你现在的任务是从这份借阅记录中计算出每个人有几个潜在朋友。
第一行两个整数N,M,2<
=N,M<
=200。
接下来有N行,第i(i=1,2,…,N)行每一行有一个数,表示读者i-1最喜欢的图书的编号P(1<
=P<
=M)
包括N行,每行一个数,第i行的数表示读者i有几个潜在朋友。
如果i和任何人都没有共同喜欢的书,则输出“BeiJu”(即悲剧,^^)
45
2
3
1
BeiJu
string.h>
intb[222];
inta[222];
intn,m;
%d%d"
&
n,&
m);
for(inti=1;
i<
=n;
i++){
a[i]);
b[a[i]]++;
}
for(inti=1;
if(b[a[i]]==1)
BeiJu\n"
elseif(b[a[i]]>
=2)
%d\n"
b[a[i]]-1);
5、称体重
赵、钱、孙、李四个人中既有大人也有小孩,给他们称体重时发现,他们每个人的体重都不一样,且体重(单位:
公斤)恰好是10的整数倍,且他们的体重都不高于50公斤,已知赵、钱两人的体重之和恰好等于孙、李两人的体重之和;
赵、李两人的体重之和大于孙、钱两人的体重之和,并且赵、孙俩人的体重之和还小于钱的体重。
请编写一个程序,按照体重从小到大的顺序,打印出四人的姓氏的首字母和体重数。
打印出四人的姓氏的首字母(小写)和体重数(每人一行,姓名首字母和体重数之间用空格隔开)。
z10
q20
s30
l40
(以上输出仅用于说明格式)
inta[4],b[4]={1,2,3,4},c[4]={'
z'
'
q'
s'
l'
};
inti,j,t;
for(a[0]=1;
a[0]<
=5;
a[0]++){
for(a[1]=1;
a[1]<
a[1]++){
for(a[2]=1;
a[2]<
a[2]++){
for(a[3]=1;
a[3]<
a[3]++){
if((a[1]!
=a[0]&
a[2]!
=a[1]&
a[3]!
=a[2]&
=a[0])
&
(a[0]+a[1]==a[2]+a[3])&
(a[0]+a[3]>
a[1]+a[2])&
(a[0]+a[2]<
a[1])){
for(i=0;
4;
b[i]=a[i];
}
}
}
}
}
a[i]=b[i];
i++){
for(j=i+1;
j++){
if(b[i]>
b[j]){
t=b[i];
b[i]=b[j];
b[j]=t;
}
for(j=0;
for(i=0;
if(a[i]==b[j]){
printf("
%c%d\n"
c[i],b[j]*10);
6、比饭量
3个人比饭量,每人说了两句话:
B比我吃的多,C和我吃的一样多?
A比我吃的多,A也比C吃的多?
我比B吃得多,B比A吃的多。
事实上,饭量和正确断言的个数是反序的关系。
请编程按饭量的大小输出3个人的顺序。
无输入
按照饭量大小输出3人顺序,比如:
ABC
intA,B,C;
inta,b,c;
for(A=1;
A<
=3;
A++){
for(B=1;
B<
B++){
for(C=1;
C<
C++){
a=((B>
A)+(C==A));
b=((A>
B)+(A>
C));
c=((C>
B)+(B>
A));
if(((A>
B&
a<
b)||(A==B&
a==b)||(A<
a>
b))
+((A>
C&
c)||(A==C&
a==c)||(A<
c))
+((B<
b>
c)||(B==C&
b==c)||(B>
b<
c))==3){
if(a>
b&
c){
if(b>
c)printf("
ABC"
elseprintf("
ACB"
}
a&
if(a>
BAC"
BCA"
if(c>
c>
b){
b)printf("
CAB"
CBA"
}
}
getchar();
return0;
7、求排列的逆序数
在Internet上的搜索引擎经常需要对信息进行比较,比如可以通过某个人对一些事物的排名来估计他(或她)对各种不同信息的兴趣,从而实现个性化的服务。
对于不同的排名结果可以用逆序来评价它们之间的差异。
考虑1,2,…,n的排列i1,i2,…,in,如果其中存在j,k,满足j<
k且?
ij>
ik,那么就称(ij,ik)是这个排列的一个逆序。
一个排列含有逆序的个数称为这个排列的逆序数。
例如排列263451含有8个逆序(2,1),(6,3),(6,4),(6,5),(6,1),(3,1),(4,1),(5,1),因此该排列的逆序数就是8。
显然,由1,2,…,n构成的所有n!
个排列中,最小的逆序数是0,对应的排列就是1,2,…,n;
最大的逆序数是n(n-1)/2,对应的排列就是n,(n-1),…,2,1。
逆序数越大的排列与原始排列的差异度就越大。
现给定1,2,…,n的一个排列,求它的逆序数。
第一行是一个整数n,表示该排列有n个数(n<
=100000)。
第二行是n个不同的正整数,之间以空格隔开,表示该排列。
输出该排列的逆序数。
6
263451
8
提示
1.利用二分归并排序算法(分治);
2.注意结果可能超过int的范围,需要用longlong存储。
cstdio>
usingnamespacestd;
constintMAX_NUM=100000+5;
longlongseq[MAX_NUM];
intN;
longlongans;
voidreSeq(longlong*seq,intlef,intrigh){//用longlong存储,避免结果超过int的范围
if(lef>
=righ){
return;
intmid=lef+(righ-lef)/2;
reSeq(seq,lef,mid);
reSeq(seq,mid+1,righ);
inttotalSize=righ-lef+1;
longlongtmp[totalSize];
intn=lef;
intm=mid+1;
inti=0;
while(n<
=mid||m<
if(m>
righ||(n<
=mid&
seq[n]<
=seq[m])){
tmp[i++]=seq[n++];
}else{
tmp[i++]=seq[m++];
ans+=mid-n+1;
i=lef;
for(intj=0;
j<
totalSize;
j++){
seq[i++]=tmp[j];
voidreSeqNum(longlong*seq,intn){
reSeq(seq,0,n-1);
intmain(){
N);
for(inti=0;
N;
i++){
%ld"
seq[i]);
ans=0;
reSeqNum(seq,N);
%ld\n"
ans);
8、Grey码
Grey码是一个长度为2n的序列,序列中无相同元素,且每个元素都是长度为n的二进制位串,相邻元素恰好只有1位不同。
例如长度为23的格雷码为(000,001,011,010,110,111,101,100)。
设计分治算法对任意的n值构造相应的Grey码。
每个元素的长度值n。
将所有相应的Grey码分行输出,即每一行输出一个二进制位串。
000
001
011
010
110
111
101
100
intpower(intbase,intn)
inti,p=1;
for(i=1;
=n;
++i)
p=p*base;
returnp;
voidGrey(inta,intb,int**arr,intk){
if(b==1){
*((int*)arr+k*0+0)=0;
//arr[0][0]=0;
*((int*)arr+k*1+0)=1;
//arr[1][0]=1;
return;
}else{
for(inti=0;
a/2;
*((int*)arr+k*i+b-1)=0;
//arr[i][b-1]=0;
*((int*)arr+k*(a-i-1)+b-1)=1;
//arr[a-i-1][b-1]=1;
Grey(a/2,b-1,(int**)arr,k);
for(inti=a/2;
a;
for(intj=0;
b-1;
*((int*)arr+k*i+j)=*((int*)arr+k*(a-i-1)+j);
//arr[i][j]=arr[a-i-1][j];
intm=(int)power(2,n);
intarr[m][n];
Grey(m,n,(int**)arr,n);
for(inti=0;
m;
for(intj=n-1;
j>
=0;
j--){
printf("
arr[i][j]);
printf("
\n"
9、循环比赛
设有N个选手的循环比赛。
其中N=2^M(2的M次方),要求每名选手要与其他N-1名选手都赛一次,每名选手每天比赛一次,循环赛共进行N-1天,要求每天没有选手轮空。
M
表格形式的比赛安排表
12345678
21436587
34127856
43218765
56781234
65872143
78563412
87654321
M的大小不会超过8
voidarrange(intk,int**a,intn){
intt=1,temp=1;
*((int*)a+k*0+0)=1;
//a[0][0]=1;
while(t<
=n){
temp;
*((int*)a+k*i+j+temp)=*((int*)a+k*i+j)+temp;
//a[i][j+temp]=a[i][j]+temp;
*((int*)a+k*(i+temp)+j)=*((int*)a+k*i+j+temp);
//a[i+temp][j]=a[i][j+temp];
*((int*)a+k*(i+temp)+j+temp)=*((int*)a+k*i+j);
//a[i+temp][j+temp]=a[i][j];
temp*=2;
t++;
intk=1;
n;
++i){
k=2*k;
inta[k][k];
arrange(k,(int**)a,n);
k;
for(intj=0;
a[i][j]);
10、棋盘覆盖问题
在一个2k×
2k个方格组成的棋盘中,若恰有一个方格与其他方格不同,称该方格为特殊方格,且称该棋盘为特殊棋盘。
显然,特殊方格在棋盘中出现的位置有4k种情形,因而有4k种不同的棋盘,如图1所示是k=2时16种棋盘中的一个。
在棋盘覆盖问题中,要求用图2所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何两个L型骨牌不得重叠覆盖。
对每一个测试例有2行,第一行是k(1<
=k<
=10),第二行是特殊方格所在的位置坐标x,y(0<
=x,y<
1024)。
边长为2的k次方的方阵,特殊方格的编号为0,所有L型骨牌从1开始编号,数据之间的间隔是空格。
01
2033
2213
4115
4455
按分治策略进行算法设计。
intt=0;
intboard[100][100];
voidChessBoard(inttr,inttc,intdr,intdc,intsize){
ints,t1;
if(size==1)return;
t1=++t;
s=size/2;
if(dr<
tr+s&
dc<
tc+s){
ChessBoard(tr,tc,dr,dc,s);
}else{
board[tr+s-1][tc+s-1]=t1;
ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
dc>
=tc+s){
ChessBoard(tr,tc+s,dr,dc,s);
board[tr+s-1][tc+s]=t1;
ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
if(dr>
=tr+s&
ChessBoard(tr+s,tc,dr,dc,s);
board[tr+s][tc+s-1]=t1;
ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
ChessBoard(tr+s,tc+s,dr,dc,s);
board[tr+s][tc+s]=t1;
ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
intn,size=1;
size=size*2;
intdr,dc;
scanf("
dr,&
dc);
ChessBoard(0,0,dr,dc,size);
size;
%d"
board[i][j]);
11、输油管道问题
某石油公司计划建造一条由东向西的主输油管道。
该管道要穿过一个有n口油井的油田。
从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。
如果给定n口油井的位置,即它们的x坐标(东西向)和y坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管道长度总和最小的位置?
证明可在线性时间内确定主管道的最优位置。
要求给定n口油井的位置,计算各油井到主管道之间的输油管道最小长度总和。
由文件提供输入数据,文件第一行是油井数n,1<
=n<
=10000。
接下来n行是油井的位置,每行两个整数x和y,-10000<
=x,y<
将结果输出到文件中,文件
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OpenJudge 算法 设计 分析 习题 解答
![提示](https://static.bdocx.com/images/bang_tan.gif)