NOIP初赛试题分类汇总完善程序部分.docx

上传人:b****4 文档编号:3067627 上传时间:2022-11-17 格式:DOCX 页数:28 大小:468.31KB
下载 相关 举报
NOIP初赛试题分类汇总完善程序部分.docx_第1页
第1页 / 共28页
NOIP初赛试题分类汇总完善程序部分.docx_第2页
第2页 / 共28页
NOIP初赛试题分类汇总完善程序部分.docx_第3页
第3页 / 共28页
NOIP初赛试题分类汇总完善程序部分.docx_第4页
第4页 / 共28页
NOIP初赛试题分类汇总完善程序部分.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

NOIP初赛试题分类汇总完善程序部分.docx

《NOIP初赛试题分类汇总完善程序部分.docx》由会员分享,可在线阅读,更多相关《NOIP初赛试题分类汇总完善程序部分.docx(28页珍藏版)》请在冰豆网上搜索。

NOIP初赛试题分类汇总完善程序部分.docx

NOIP初赛试题分类汇总完善程序部分

 

NOIP初赛试题分类汇总_完善程序部分(总20页)

NOIP初赛试题汇总

完善程序

'2004

1.Joseph

题目描述:

原始的Joseph问题的描述如下:

有n个人围坐在一个圆桌周围,把这n个人依次编号为1,…,n。

从编号是1的人开始报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m个人又出列,…,如此反复直到所有的人全部出列为止。

比如当n=6,m=5的时候,出列的顺序依次是5,4,6,2,3,1。

现在的问题是:

假设有k个好人和k个坏人。

好人的编号的1到k,坏人的编号是k+1到2k。

我们希望求出m的最小值,使得最先出列的k个人都是坏人。

输入:

仅有的一个数字是k(0

输出:

使得最先出列的k个人都是坏人的m的最小值。

输入样例:

4

输出样例:

30

程序:

#include<>

longk,m,begin;

intcheck(longremain){

longresult=(①)%remain;

if(②){

begin=result;return1;

}

elsereturn0;

}

intmain(){

longi,find=0;

scanf("%ld",&k);

for(m=k;③;m++){

find=1;begin=0;

for(i=0;i

if(!

check(④)){

find=0;break;

}

}

printf("%ld\n",⑤);

return0;

}

2.逻辑游戏

题目描述:

一个同学给了我一个逻辑游戏。

他给了我图1,在这个图上,每一段边界都已经进行了编号。

我的任务是在图中画一条连续的曲线,使得这条曲线穿过每一个边界一次且仅穿过一次,而且曲线的起点和终点都在这整个区域的外面。

这条曲线是容许自交的。

对于图1,我的同学告诉我画出这样的一条曲线(图2)是不可能的,但是对于有的图形(比如图3),画出这样一条曲线是可行的。

对于给定的一个图,我想知道是否可以画出满足要求的曲线。

图1

图2

图3

图4

输入:

输入的图形用一个n×n的矩阵表示的。

矩阵的每一个单元里有一个0到255之间(包括0和255)的整数。

处于同一个区域的单元里的数相同,相邻区域的数不同(但是不相邻的区域里的数可能相同)。

输入的第一行是n(0

以下的n行每行包括n个整数,分别给出对应的单元里的整数(这n个整数之间用空格分开)。

图4给出了输入样例对应的图形。

输出:

当可以画出满足题意的曲线的时候,输出“YES”;否则,输出“NO”。

输入样例:

3

112

122

112

输出样例:

YES

程序:

#include<>

#include<>

intorig,n,ns,a[102][102],bun;

intd[]={1,0,-1,0,0,1,①};

voidplimba(intx,inty){

inti,x1,y1;

a[x][y]=-a[x][y];

if(abs(a[x-1][y])!

=orig&&(②!

=a[x-1][y]

||abs(a[x][y-1])!

=orig))ns++;

if(abs(a[x+1][y])!

=orig&&(a[x+1][y-1]!

=a[x+1][y]

||abs(a[x][y-1])!

=orig))ns++;

if(abs(a[x][y-1])!

=orig&&(③!

=a[x][y-1]

||abs(a[x-1][y])!

=orig))ns++;

if(abs(a[x][y+1])!

=orig&&(a[x-1][y+1]!

=a[x][y+1]

||abs(a[x-1][y])!

=orig))ns++;

for(i=0;i<4;i++){

x1=x+d[2*i];y1=y+④;

if(x1>=1&&x1<=n&&y1>=1&&y1<=n&&⑤)

plimba(x1,y1);

}

}

intmain(){

inti,j;

bun=1;

scanf("%d",&n);

for(i=0;i<=n+1;i++)

for(j=0;j<=n+1;j++)a[i][j]=0;

a[0][0]=-1;a[n+1][0]=-1;

a[0][n+1]=-1;a[n+1][n+1]=-1;

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)scanf("%d",&(a[i][j]));

for(i=1;i<=n;i++)

for(j=1;j<=n;j++){

if(a[i][j]>-1){

ns=0;⑥;

plimba(i,j);

if(ns%2==1)bun=0;

}

}

if(bun)printf("YES\n");elseprintf("NO\n");

return0;

}

'2005

1.木材加工

题目描述:

木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头(木头有可能有

剩余),需要得到的小段的数目是给定了的。

当然,我们希望得到的小段越长越好,你的任

务是计算能够得到的小段木头的最大长度。

木头长度的单位是cm。

原木的长度都是正整数,我们要求切割得到的小段木头的长度

也是正整数。

输入:

第一行是两个正整数N和K(1≤N≤10000,1≤K≤10000),N是原木的数目,

K是需要得到的小段的数目。

接下来的N行,每行有一个1到10000之间的正整数,表示一根原木的长度。

输出:

输出能够切割得到的小段的最大长度。

如果连1cm长的小段都切不出来,输出”0”。

输入样例:

37

232

124

456

输出样例:

114

程序:

#include<>

intn,k,len[10000];

intisok(intt){

intnum=0,i;

for(i=0;i

if(num>=k)break;

num=①;

}

if(②)return1;

elsereturn0;

}

intmain(){

inti,left,right,mid;

scanf("%d%d",&n,&k);

right=0;

for(i=0;i

scanf("%d",&(len[i]));

if(right

}

right++;

③;

while(④

mid=(left+right)/2;

if(⑤)right=mid;

elseleft=mid;

}

printf("%d\n",left);

return0;

}

2.N叉树

题目描述:

我们都了解二叉树的先根遍历,中根遍历和后根遍历。

当知道先根遍历的结果和中根遍

历结果的时候,我们可以唯一的确定二叉树;同样的,如果知道了后根遍历的结果和中根遍

历结果,二叉树也是唯一确定的。

但是如果只知道先根遍历和后根遍历的结果,二叉树就不

是唯一的了。

但是我们可以计算满足条件的不同二叉树的一共有多少个。

这不是一个很困难

的问题,稍微复杂一点,我们把这个问题推广到N叉树。

我们用小写英文字母来表示N叉树的结点,不同的结点用不同的字母表示。

比如,对

于4叉树,如果先根遍历的结果是abdefgc,后根遍历的结果是defgbca,那么我们可以

得到6个不同的4叉树(如下图)。

输入:

输入数据包括3行。

第一行是一个正整数N(1≤N≤20),表示我们要考虑N叉树。

第二行和第三行分别是两个字符串序列,分别表示先根遍历和后根遍历的结果。

输出:

输出不同的N叉树的数目。

题目中给的数据保证得到的结果小于2

31

输入样例:

4

abdefgc

defgbca

输出样例:

6

程序:

#include<>

#include<>

charstr1[100],str2[100];

intN;

longcom[100][100];

longgetcom(intx,inty){

if(y==0||x==y)①;

elseif(com[x][y]!

=0)returncom[x][y];

else{

com[x][y]=getcom(x-1,y)+②;

returncom[x][y];

}

}

longcount(inta,intb,intc){

longsum=1;

intk=0;

ints=a+1,t=c,p;

if(a==b)return1;

while(s<=b){

p=t;

while(str1[s]!

=str2[t])t++;

sum=sum*count(s,s+t-p,p);

s=③;

④;

k++;

}

return⑤*getcom(N,k);

}

intmain(){

intlen;

scanf("%d",&N);

scanf("%s%s",str1,str2);

len=strlen(str1);

printf("%ld\n",count(⑥));

return0;

}

'2006

1.(选排列)下面程序的功能是利用递归方法生成从1到n(n<10)的n个数中取k(1<=k<=n)个数的

全部可能的排列(不一定按升序输出)。

例如,当n=3,k=2时,应该输出(每行输出5个排列):

1213212332

31

程序:

#include<>

intn,k,a[10];

longcount=0;

voidperm2(intj)

{inti,p,t;

if(①)

{for(i=k;i<=n;i++)

{count++;

t=a[k];a[k]=a[i];a[i]=t;

for(②)

printf("%1d",a[p]);/*"%1d"中是数字1,不是字母l*/

printf("");

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 文化宗教

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1