NOIP初赛试题分类汇总完善程序部分Word文档格式.docx
《NOIP初赛试题分类汇总完善程序部分Word文档格式.docx》由会员分享,可在线阅读,更多相关《NOIP初赛试题分类汇总完善程序部分Word文档格式.docx(28页珍藏版)》请在冰豆网上搜索。
>
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<
k;
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<
100)。
以下的n行每行包括n个整数,分别给出对应的单元里的整数(这n个整数之间用空格分开)。
图4给出了输入样例对应的图形。
当可以画出满足题意的曲线的时候,输出“YES”;
否则,输出“NO”。
3
112
122
YES
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])!
(a[x+1][y-1]!
=a[x+1][y]
if(abs(a[x][y-1])!
(③!
=a[x][y-1]
||abs(a[x-1][y])!
if(abs(a[x][y+1])!
(a[x-1][y+1]!
=a[x][y+1]
for(i=0;
4;
i++){
x1=x+d[2*i];
y1=y+④;
if(x1>
=1&
x1<
=n&
y1>
y1<
⑤)
plimba(x1,y1);
inti,j;
bun=1;
%d"
n);
=n+1;
for(j=0;
j<
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;
=n;
i++)
for(j=1;
j++)scanf("
(a[i][j]));
=n;
for(j=1;
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"
2005
1.木材加工
木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头(木头有可能有
剩余),需要得到的小段的数目是给定了的。
当然,我们希望得到的小段越长越好,你的任
务是计算能够得到的小段木头的最大长度。
木头长度的单位是cm。
原木的长度都是正整数,我们要求切割得到的小段木头的长度
也是正整数。
第一行是两个正整数N和K(1≤N≤10000,1≤K≤10000),N是原木的数目,
K是需要得到的小段的数目。
接下来的N行,每行有一个1到10000之间的正整数,表示一根原木的长度。
输出能够切割得到的小段的最大长度。
如果连1cm长的小段都切不出来,输出”0”。
37
232
124
456
114
intn,k,len[10000];
intisok(intt){
intnum=0,i;
n;
i++){
if(num>
=k)break;
num=①;
}
if(②)return1;
intmain(){
inti,left,right,mid;
%d%d"
n,&
right=0;
(len[i]));
if(right<
len[i])right=len[i];
}
right++;
③;
while(④<
right){
mid=(left+right)/2;
if(⑤)right=mid;
elseleft=mid;
printf("
%d\n"
left);
2.N叉树
我们都了解二叉树的先根遍历,中根遍历和后根遍历。
当知道先根遍历的结果和中根遍
历结果的时候,我们可以唯一的确定二叉树;
同样的,如果知道了后根遍历的结果和中根遍
历结果,二叉树也是唯一确定的。
但是如果只知道先根遍历和后根遍历的结果,二叉树就不
是唯一的了。
但是我们可以计算满足条件的不同二叉树的一共有多少个。
这不是一个很困难
的问题,稍微复杂一点,我们把这个问题推广到N叉树。
我们用小写英文字母来表示N叉树的结点,不同的结点用不同的字母表示。
比如,对
于4叉树,如果先根遍历的结果是abdefgc,后根遍历的结果是defgbca,那么我们可以
得到6个不同的4叉树(如下图)。
输入数据包括3行。
第一行是一个正整数N(1≤N≤20),表示我们要考虑N叉树。
第二行和第三行分别是两个字符串序列,分别表示先根遍历和后根遍历的结果。
输出不同的N叉树的数目。
题目中给的数据保证得到的结果小于2
31
。
4
abdefgc
defgbca
6
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;
N);
%s%s"
str1,str2);
len=strlen(str1);
count(⑥));
2006
1.(选排列)下面程序的功能是利用递归方法生成从1到n(n<
10)的n个数中取k(1<
=k<
=n)个数的
全部可能的排列(不一定按升序输出)。
例如,当n=3,k=2时,应该输出(每行输出5个排列):
1213212332
31
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(②)
%1d"
a[p]);
/*"
中是数字1,不是字母l*/
"