word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx

上传人:b****6 文档编号:8356600 上传时间:2023-01-30 格式:DOCX 页数:58 大小:25.08KB
下载 相关 举报
word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx_第1页
第1页 / 共58页
word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx_第2页
第2页 / 共58页
word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx_第3页
第3页 / 共58页
word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx_第4页
第4页 / 共58页
word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx_第5页
第5页 / 共58页
点击查看更多>>
下载资源
资源描述

word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx

《word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx》由会员分享,可在线阅读,更多相关《word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx(58页珍藏版)》请在冰豆网上搜索。

word完整版NOIP提高组初赛历年试题及答案阅读题篇docx.docx

word完整版NOIP提高组初赛历年试题及答案阅读题篇docx

 

NOIP提高组初赛历年试题及答案阅读题篇

程序写果(共4,每8分,共32分)

 

程序的最好方法并非是依次从到尾。

程序不像迷,我无法从末尾几找到答案,也不像一本引人入的籍,只需直接翻到褶最多的那几,我就能找到最精彩的片断。

因此我在程序,最好逐一考察研究每一段代,搞清楚每一段代的来去脉,理解每一段代在程序中所起的作用,而形成一个虚的程序构,并以此基来行。

 

1、分:

高入手,逐深入,正确理解程序。

2、写注解:

固化、、提已有的理解成果。

3、先模:

根据代序跟踪量,模运算。

4、找律:

先模几次循后,找出背后的律。

5、看功能:

从代构和运算果判断程序功能。

6、猜算法:

有不知道算法,通构和函数猜一猜。

7、方法:

了解程序本后,一个熟悉的方法。

 

大多数人来,写程序是令人开心的一件事情,人的程序却很痛苦,很恐惧,宁愿自己重写一遍。

其到好的程序,就像一篇美文,令人心神怡,

豁然开朗,因背后是一个人的思,甚至整个人生。

 

人的程序不可以巩固自己的知,启自己的思,提升自己的修养,你收,其,也是在学、在、在工作中的最重要、最常用的基本功。

 

如果写程序是把自己的思化代,程序就是把代化你理解的人的思。

当你程序有烈的代入感,像演一,真正入到的精神世界,面部表情也随之日丰富起来。

祝你!

你通关了!

 

之,看得多,得多,拼得多,你就考得多⋯⋯

 

NOIP2011-1.

#include

 

#include

 

usingnamespacestd;

 

constintSIZE=100;

 

intmain()

 

{

 

intn,i,sum,x,a[SIZE];

 

cin>>n;

 

memset(a,0,sizeof(a));

 

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

 

cin>>x;

 

a[x]++;

 

}

 

i=0;

 

sum=0;

 

while(sum<(n/2+1)){

 

i++;

 

sum+=a[i];

 

}

 

cout<

 

return0;

 

}

输入:

 

11

 

45664332321

 

一步步模拟,注意输出的是sum超出循环条件时的i值(中位数),而不是sum,也不是

 

a[x]

输出:

3

 

NOIP2011-2.

#include

 

usingnamespacestd;

 

intn;

 

voidf2(intx,inty);

 

voidf1(intx,inty)

 

{

 

if(x

 

f2(y,x+y);

 

}

 

voidf2(intx,inty)

 

{

 

cout<

 

f1(y,x+y);

 

}

 

intmain()

 

{

 

cin>>n;

 

f1(0,1);

 

return0;

 

}

 

输入:

30

 

此为简单的递归题,依次输出f2(x,y)中的x值,注意边界条件时f1(x,y)的x>=30

 

咦!

这不是隔一个输出一个的Fibonacci吗?

 

输出:

1251334

 

NOIP2011-3.

#include

 

usingnamespacestd;

 

constintV=100;

 

intn,m,ans,e[V][V];

 

boolvisited[V];

 

voiddfs(intx,intlen)

 

{

 

inti;

 

visited[x]=true;

 

if(len>ans)

 

ans=len;

 

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

 

if((!

visited[i])&&(e[x][i]!

=-1))

 

dfs(i,len+e[x][i]);

 

visited[x]=false;

 

}

 

intmain()

 

{

 

inti,j,a,b,c;

 

cin>>n>>m;

 

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

 

for(j=1;j<=m;j++)

 

e[i][j]=-1;

 

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

 

{

 

cin>>a>>b>>c;

 

e[a][b]=c;

 

e[b][a]=c;

 

}

 

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

 

visited[i]=false;

 

ans=0;

 

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

 

dfs(i,0);

 

cout<

 

return0;

 

}

输入:

 

46

 

1210

 

2320

 

3430

 

4140

 

1350

 

2460

 

一看就知这是深搜算法(DFS),输入是个四个顶点的无向图(邻接矩阵如下):

 

 

len>ans

 

,则ans=len

 

,可以说明这是个在图中用

 

DFS

 

找最长的路径的程序。

 

DFS

 

以任

 

意点作为起点,找一条路径,本次走过的点不走,找到没路走为止。

由于就

4个点,最多

 

就走

 

3

 

条边,看看最长的那

 

3条,结果如下图:

 

输出:

150

 

NOIP2011-4.

#include

 

#include

 

#include

 

usingnamespacestd;

 

constintSIZE=10000;

 

constintLENGTH=10;

 

intn,m,a[SIZE][LENGTH];

 

inth(intu,intv)

 

{

 

intans,i;

 

ans=0;

 

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

 

if(a[u][i]!

=a[v][i])

 

ans++;

 

returnans;

 

}

 

intmain()

 

{

 

intsum,i,j;

 

cin>>n;

 

memset(a,0,sizeof(a));

 

m=1;

 

while

(1)

 

{

 

i=1;

 

while((i<=n)&&(a[m][i]==1))

 

i++;

 

if(i>n)

 

break;

 

m++;

 

a[m][i]=1;

 

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

 

a[m][j]=a[m-1][j];

 

}

 

sum=0;

 

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

 

for(j=1;j<=m;j++)

 

sum+=h(i,j);

 

cout<

 

return0;

 

}

 

输入:

7

 

根据while

(1)的程序功能模拟几行看看,观察m*n的0-1矩阵,此矩阵其实就是所有7

 

位的二进制数(顺序左右颠倒),m=2^n。

再根据h(u,v)的程序功能判断出本程序的目的。

 

每一列中有

2^n-1

个1和0,在一列里每个1

都有2^(n-1)

个0

与它不同,同样每个0

也有2^(n-1)

个1

与它不同,即每列的结果为

2^(2n-2)*2=2^(2n-1)

,n列的结果为

n*2^(2n-1)

,所以本题的结果为2^13*7。

输出:

57344

 

NOIP2012-1.

 

#include

 

usingnamespacestd;

 

intn,i,temp,sum,a[100];

 

intmain()

 

{

 

cin>>n;

 

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

 

cin>>a[i];

 

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

 

if(a[i]>a[i+1]){

 

temp=a[i];

 

a[i]=a[i+1];

 

a[i+1]=temp;

 

}

 

for(i=n;i>=2;i--)

 

if(a[i]

 

temp=a[i];

 

a[i]=a[i-1];

 

a[i-1]=temp;

 

}

 

sum=0;

 

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

 

sum+=a[i];

 

cout<

 

return0;

 

}

输入:

 

8

 

4070507020401030

两轮冒泡,掐头去尾,求均值。

数据量不大,就直接模拟吧,速度也挺快的。

 

输出:

41

 

NOIP2012-2.

 

#include

 

usingnamespacestd;

 

intn,i,ans;

 

intgcd(inta,intb)

 

{

 

if(a%b==0)

 

returnb;

 

else

 

returngcd(b,a%b);

 

}

 

intmain()

 

{

 

cin>>n;ans=0;

 

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

 

if(gcd(n,i)==i)

 

ans++;

 

cout<

 

return0;

 

}

 

输入:

120

 

gcd就是求最大公约数,如果gcd(n,i)==i则计数,即求120的因子数。

 

输出:

16

 

NOIP2012-3.

 

#include

 

usingnamespacestd;

 

constintSIZE=20;

 

intdata[SIZE];

 

intn,i,h,ans;

 

voidmerge()

 

{

 

data[h-1]=data[h-1]+data[h];

 

h--;

 

ans++;

 

}

 

intmain()

 

{

 

cin>>n;

 

h=1;

 

data[h]=1;

 

ans=0;

 

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

 

{

 

h++;

 

data[h]=1;

 

while(h>1&&data[h]==data[h-1])

 

merge();

 

}

 

cout<

 

return0;

 

}

 

输入:

8

 

继续模拟,while语句中函数调用细心点即可。

 

输出:

7

 

输入:

2012

 

对前面的模拟进行观察,得出如下规律后计算:

 

i=2012=512+256+128+64+16+8+4

 

即data[1]=512data[2]=256data[3]=128data[4]=64data[5]=16data[6]=8

 

data[7]=4

 

ans=512-1+256-1+128-1+64-1+16-1+8-1+4-1=2004

 

输出:

2004

 

NOIP2012-4.

 

#include

 

#include

 

usingnamespacestd;

 

intlefts[20],rights[20],father[20];

 

strings1,s2,s3;

 

intn,ans;

 

voidcalc(intx,intdep)

 

{

 

ans=ans+dep*(s1[x]-'A'+1);

 

if(lefts[x]>=0)calc(lefts[x],dep+1);

 

if(rights[x]>=0)calc(rights[x],dep+1);

 

}//递归函数,返回ans,累计结点深度*结点权值之和

 

voidcheck(intx)

 

{

 

if(lefts[x]>=0)check(lefts[x]);

 

s3=s3+s1[x];

 

if(rights[x]>=0)check(rights[x]);

 

}

 

voiddfs(intx,intth)

 

{

 

if(th==n)

 

{

 

s3="";

 

check(0);

 

if(s3==s2)

 

{

 

ans=0;

 

calc(0,1);

 

cout<

 

}//输出递归函数calc(0,1)的值

 

return;

 

}

 

if(lefts[x]==-1&&rights[x]==-1)

 

{

 

lefts[x]=th;

 

father[th]=x;

 

dfs(th,th+1);

 

father[th]=-1;

 

lefts[x]=-1;

 

}

 

if(rights[x]==-1)

 

{

 

rights[x]=th;

 

father[th]=x;

 

dfs(th,th+1);

 

father[th]=-1;

 

rights[x]=-1;

 

}

 

if(father[x]>=0)

 

dfs(father[x],th);

 

}

 

intmain()

 

{

 

cin>>s1;//

 

先序遍历序列

 

cin>>s2;//

 

n=s1.size();

 

中序遍历序列

 

memset(lefts,-1,sizeof(lefts));

 

memset(rights,-1,sizeof(rights));

 

memset(father,-1,sizeof(father));

 

dfs(0,1);

 

}

输入:

 

ABCDEF

 

BCAEDF

这是二叉树的遍历题,先根据两个输入的遍历序列确定二叉树。

再根据递归函数计算六个结点深度*权值之和:

 

ans=1*1+2*2+3*3+4*2+5*3+6*3

 

输出:

55

 

NOIP2013-1.

#include

 

#include

 

usingnamespacestd;

 

intmain()

 

{

 

stringStr;

 

cin>>str;

 

intn=str.size();

 

boolisPlalindrome=true;

 

for(inti=0;i

 

if(str[i]!

=str[n-i-1])

 

}

 

isPlalindrome=false;

 

if(isPlalindrome)

 

cout<<”Yes”<

 

else

 

cout<<”No”<

 

}

 

输入:

abceecba

 

判断输入的是不是一个回文串,字符串左右颠倒,结果不变。

 

输出:

Yes

 

NOIP2013-2.

#include

 

usingnamespacestd;

 

intmain()

 

{

 

inta,b,u,v,i,num;

 

cin>>a>>b>>u>>v;

 

num=0;

 

for(i=a;I<=b;i++)

 

if(((i%u)==0)||((i%v)==0))

 

num++;

 

count<

 

return0;

 

}

 

输入:

110001015

 

1-1000范围内同时是10、15的倍数有多少?

注意去重。

 

输出:

133

 

NOIP2013-3.

#include

 

usingnamespacestd;

 

intmain()

 

{

 

constintSIZE=100;

 

intheight[SIZE],num[SIZE],n,ans;

 

cin>>n;

 

for

(inti=0;

i

i++){

cin>>height[i];

num[i]=1;

for

(intj=0;

j

j++){

 

if((height[j]=num[i]))

 

num[i]=num[j]+1;

 

}

 

}

 

ans=0;

 

for(intI=1;i

 

if(num[i]>ans)ans=num[j];

 

}

 

cout<

 

return0;

 

}

输入:

 

8

 

32511127410

求该字符串的最长上升子序列的长度。

输出:

4

 

NOIP2013-4.

#include

 

#include

usingnamespace

std;

const

int

SIZE=100;

int

n,m,p,

a[SIZE][SIZE],count;

void

colour

(intx,

int

y)

{

Count++;

a[x][y]=1;

if((x>1)&&(a[x-1][y]

==0))

colour(x-1,y);

if((y>1)&&(a[x][y-1]

==0))

colour(x,y-1);

if((x

==0))

colour(x+1,y);

if((y

==0))

colour(x,y+1);

}

 

intmain()

 

{

 

inti,j,x,y,ans;

 

memset(a,0,sizeof(a));

 

cin>>n>>m>>p;

 

for(i=1;I<=p;

i++){

cin>>x>>y;

a[x][y]

=1;

}

ans

=

0;

for

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

for

(j=1;j<=m;j++)

if(a[i][j]

==

0){

count

=0;

colour

(i,j);

 

if(ans

 

ans

 

}

 

count<

 

return0;

 

}

输入:

 

659

 

14

 

23

 

24

 

32

 

41

 

43

 

45

 

54

 

64

 

根据输入的x和y值画出0-1矩阵,再判断同一区域0最多的个数

 

输出:

7

 

NOIP2014-1.

#include

 

usingnamespacestd;

 

intmain()

 

{

 

inta,b,i,tot,c1,c2;

 

cin>>a>>b;

 

tot=0;

 

for(i=a;i<=b;i++)

 

{

 

c1=i/10;

 

c2=i%10;

 

if((c1+c2)%3==0)

 

tot++;//一个数的各位数之和是3的倍数,它就是3的倍数。

 

}

 

cout<

 

return0;

 

}//统计7-31之间有多少数是3的倍数输入:

731

 

输出:

8

 

NOIP2014-2.

#include

 

usingnamespacestd;

 

intfun(intn,intminNum,intmaxNum)

 

{

 

inttot,i;

 

if(n==0)

 

return1;

 

tot=0;

 

for(i=minNum;i<=maxNum;i++)

 

tot+=fun(n-1,i+1,maxNum);

 

returntot;

 

}

 

intmain()

 

{

 

intn,m;

 

cin>>n>>m;

 

cout<

 

return0;

 

}

 

输入:

63

 

递归边界:

当n=0时,fun(n,minNum,maxNum)=1

 

fun(3,1,6)=(2,2,6)+(2,3,6)+(2,4,6)+(2,5,6)+(2,6,6)+(2,7,6)=20

 

fun(2,2,6)=(1,3,6)+(1,4,6)+(1,5,6)+(1,6,6)+(1,7,6)=10

 

fun(2,3,6)=(1,4,6)+(1,5,6)+(1,6,6)+(1,7,6)=6

 

fun(2,4,6)=(1,5,6)+(1,6,6)+(1,7,6)=3

 

fun(2,5,

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

当前位置:首页 > 考试认证 > 司法考试

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

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