return0;
}
输入:
16
输出:
______________
4.
#include
#include
usingnamespacestd;
constintSIZE=100;
intn,m,r[SIZE];
boolmap[SIZE][SIZE],found;
boolsuccessful()
{
inti;
for(i=1;i<=n;i++)
if(!
map[r[i]][r[i%n+1]])
returnfalse;
returntrue;
}
voidswap(int*a,int*b)
{
intt;
t=*a;
*a=*b;
*b=t;
}
voidperm(intleft,intright)
{
inti;
if(found)
return;
if(left>right)
{
if(successful())
{
for(i=1;i<=n;i++)
cout<found=true;
}
return;
}
for(i=left;i<=right;i++)
{
swap(r+left,r+i);
perm(left+1,right);
swap(r+left,r+i);
}
}
intmain()
{
intx,y,i;
cin>>n>>m;
memset(map,false,sizeof(map));
for(i=1;i<=m;i++)
{
cin>>x>>y;
map[x][y]=true;
map[y][x]=true;
}
for(i=1;i<=n;i++)
r[i]=i;
found=false;
perm(1,n);
if(!
found)
cout<<"Nosolution!
"<return0;
}
输入:
912
12
23
34
45
56
61
17
27
38
48
59
69
输出:
_________
5.完善程序(第1空2分,其余10空,每空2.5分,共27分)
1.(过河问题)在一个月黑风高的夜晚,有一群人在河的右岸,想通过唯一的一根独木桥走到河的左岸.在伸手不见五指的黑夜里,过桥时必须借照灯光来照明,不幸的是,他们只有一盏灯.另外,独木桥上最多能承受两个人同时经过,否则将会坍塌.每个人单独过独木桥都需要一定的时间,不同的人要的时间可能不同.两个人一起过独木桥时,由于只有一盏灯,所以需要的时间是较慢的那个人单独过桥所花费的时间.现在输入N(2<=N<1000)和这N个人单独过桥需要的时间,请计算总共最少需要多少时间,他们才能全部到达河左岸.
例如,有3个人甲、乙、丙,他们单独过桥的时间分别为1、2、4,则总共最少需要的时间为7.具体方法是:
甲、乙一起过桥到河的左岸,甲单独回到河的右岸将灯带回,然后甲、丙在一起过桥到河的左岸,总时间为2+1+4=7.
#include
#include
usingnamespacestd;
constintSIZE=100;
constintINFINITY=10000;
constboolLEFT=true;
constboolRIGHT=false;
constboolLEFT_TO_RIGHT=true;
constboolRIGHT_TO_LEFT=false;
intn,hour[SIZE];
boolpos[SIZE];
intmax(inta,intb)
{
if(a>b)
returna;
else
returnb;
}
intgo(boolstage)
{
inti,j,num,tmp,ans;
if(stage==RIGHT_TO_LEFT)
{
num=0;
ans=0;
for(i=1;i<=n;i++)
if(pos[i]==RIGHT)
{
num++;
if(hour[i]>ans)
ans=hour[i];
}
if(①)
returnans;
ans=INFINITY;
for(i=1;i<=n-1;i++)
if(pos[i]==RIGHT)
for(j=i+1;j<=n;j++)
if(pos[j]==RIGHT)
{
pos[i]=LEFT;
pos[j]=LEFT;
tmp=max(hour[i],hour[j])+②;
if(tmpans=tmp;
pos[i]=RIGHT;
pos[j]=RIGHT;
}
returnans;
}
if(stage==LEFT_TO_RIGHT)
{
ans=INFINITY;
for(i=1;i<=n;i++)
if(③)
{
pos[i]=RIGHT;
tmp=④;
if(tmpans=tmp;
⑤;
}
returnans;
}
return0;
}
intmain()
{
inti;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>hour[i];
pos[i]=RIGHT;
}
cout<return0;
}
2.(烽火传递)烽火台又称烽燧,是重要的军事防御设施,一般建在险要处或交通要道上。
一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息;夜晚燃烧干柴,以火光传递军情。
在某两座城市之间有n个烽火台,每个烽火台发出信号都有一定的代价。
为了使情报准确地传递,在连续的m个烽火台中至少要有一个发出信号。
现输入n、m和每个烽火台发出信号的代价,请计算总共最少花费多少代价,才能使敌军来袭之时,情报能在这两座城市之间准确传递。
例如,有5个烽火台,他们发出信号的代价依次为1,2,5,6,2,,且m为3,则总共最少花费代价为4,即由第2个和第5个烽火台发出信号。
#include
#include
usingnamespacestd;
constintSIZE=100;
intn,m,r,value[SIZE],heap[SIZE],
pos[SIZE],home[SIZE],opt[SIZE];
//hep[i]表示用顺序数组储存的堆heap中第i个元素的值
//pos[i]表示opt[i]在堆heap中的位置,即heap[pos[i]]=opt[i]
//home[i]表示heap[i]在序列opt中的位置,即opt[home[i]]=heap[i]
voidswap(inti,intj)//交换堆中的第i个和第j个元素
{
inttmp;
pos[home[i]]=j;
pos[home[j]]=i;
tmp=heap[i];
head[i]=head[j];
heap[j]=tmp;
tmp=home[i];
home[i]=home[j];
home[j]=tmp;
}
voidadd(intk)//在堆中插入opt[k]
{
inti;
r++;
heap[r]=①;
pos[k]=r;
②;
i=r;
while((i>1)&&(heap[i]{
swap(i,i/2);
i/=2;
}
}
voidremove(intk)//在堆中删除opt[k]
{
inti,j;
i=pos[k];
swap(i,r);;
r--;
if(i==r+1)
return;
while((i>1)&&(heap[i]{
swap(i,i/2);
i/=2;
}
while(i+i<=r)
{
if((i+i+1<=r)&&(heap[i+i+1]j=i+i+1;
else
③;
if(hea[i]>heap[j])
{
④;
i=j;
}
else
break;
}
}
intmain()
{
inti;
cin>>n>>m;
for(i=1;i<=n;i+++)
cin>>value[i];
r=0;
for(i=1;i<=m;i++)
{
opt[i]=value[i];
add(i);
}
for(i=m+1;i<=n;i++)
{
opt[i]=⑤;
remove(⑥);
add(i);
}
cout<return0;
}
NOIP2010年提高组(C++语言)参考答案与评分标准
一、单项选择题:
(每题1.5分)
1
2
3
4
5
6
7
8
9
10
C
A
A
D
B
D
C
B
C
B
2、不定项选择题(共10题,每题1.5分,共计15分。
每题正确答案的个数大于或等于1。
多选或少选均不得分)。
1
2
3
4
5
6
7
8
9
10
ACD
AD
ABD
AC
B
B
D
D
BCD
ABC
三、问题求解:
(共3题,每空5分,共计15分)
1.yyxyxxyyxyxyxxxxyx
2.12
3.18
四、阅读程序写结果(共4题,每题7分,共计28分)
1.16
2.12356791014
3.4
4.169548327
五、、完善程序(第1空2分,其余10空,每空2.5分,共计27分)
(说明:
以下各程序填空可能还有一些等价的写法,各省可请本省专家审定和上机验证,不一定上报科学委员会审查)
1.
①num<=2(或num<3或num=2)
②go(LEFT_TO_RIGHT)
③pos[i]==LEFT(或LEFT=pos[i])
④hour[i]+go(RIGHT_TO_LEFT)(或go(RIGHT_TO_LEFT)+hour[i])
⑤pos[i]=LEFT
本小题中,LEFT可用true代替,LEFT_TO_RIGHT可用true代替,RIGHT_TO_LEFT可用false代替。
2.
①opt[k]
②home[r]=k
③j=i+i(或j=2*i或j=i*2)
④swap(i,j)(或swap(j,i))
⑤value[i]+heap[1](或heap[1]+value[i])
⑥i-m