河南省信息学奥林匹克竞赛高中选拔赛.docx

上传人:b****2 文档编号:2240537 上传时间:2022-10-28 格式:DOCX 页数:22 大小:41.71KB
下载 相关 举报
河南省信息学奥林匹克竞赛高中选拔赛.docx_第1页
第1页 / 共22页
河南省信息学奥林匹克竞赛高中选拔赛.docx_第2页
第2页 / 共22页
河南省信息学奥林匹克竞赛高中选拔赛.docx_第3页
第3页 / 共22页
河南省信息学奥林匹克竞赛高中选拔赛.docx_第4页
第4页 / 共22页
河南省信息学奥林匹克竞赛高中选拔赛.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

河南省信息学奥林匹克竞赛高中选拔赛.docx

《河南省信息学奥林匹克竞赛高中选拔赛.docx》由会员分享,可在线阅读,更多相关《河南省信息学奥林匹克竞赛高中选拔赛.docx(22页珍藏版)》请在冰豆网上搜索。

河南省信息学奥林匹克竞赛高中选拔赛.docx

河南省信息学奥林匹克竞赛高中选拔赛

2012年河南省信息学奥林匹克竞赛(高中)选拔赛(上午)

第一题:

音量调节(changingsounds)

时间限制:

1秒

输入:

changingsounds.in

输出:

changingsounds.out

问题描述

一个吉他手准备参加一场演出。

他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。

在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。

每一次改变音量,他可以选择调高也可以调低。

音量用一个整数描述。

输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。

音量不能小于0也不能大于maxLevel。

输入文件中还给定了n个整数,表示在第i首歌开始之前吉他手想要改变的音量是多少。

吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。

输入

第一行依次为三个整数:

n,beginLevel,maxlevel。

第二行依次为n个整数:

输出

输出演奏最后一首歌的最大音量。

如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。

样例1

输入输出

351010

537

样例2

输入输出

4820-1

152910

数据规模

,,,。

第二题外星人(alien)

时间限制:

1秒

输入文件:

alien.in

输出文件:

alien.out

问题描述

艾莉欧在她的被子上发现了一个数字,她觉得只要找出最小的使得,。

根据这个她就能找到曾经绑架她的外星人的线索了。

当然,她是不会去算,请你帮助她算出最小的x。

输入

第一行一个正整数test,接下来test组数据每组数据第一行一个正整数,接下来行每行两个正整数。

其中为的标准分解形式。

输出

输出test行,每行一个整数,表示答案。

样例输入

1

2

22

31

样例输出

3

样例解释

所以答案是3。

数据规模

30%的数据,,60%的数据,,100%的数据,

第三题:

道路(road)

时间限制:

3秒

输入文件:

road.in

输出文件:

road.out

问题描述

C国有n座城市,城市之间通过m条单向道路连接。

一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。

两条最短路不同,当且仅当它们包含的道路序列不同。

我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。

现在,这个任务交给了你。

输入

第一行包含两个正整数n、m

接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路

输出

输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果

样例输入

44

125

235

345

148

样例输出

2

3

2

1

数据规模

30%的数据满足:

n≤15、m≤30

60%的数据满足:

n≤300、m≤1000

100%的数据满足:

n≤1500、m≤5000、w≤10000

HAOI2012题解

第一题:

音量调节(changingsounds)

这道题是送分题。

如果不会做的话,还是不要继续看下去了,多做题多学算法提高水平,省选难度不适合你。

Dp解决。

用f[i][j]表示进行前i次操作,音量能否达到j

f[i][j]=f[i-1][j-c[i]]orf[i-1][j+c[i]]

复杂度O(nmaxlevel)

代码:

programchangingsounds;

var

ans,n,b,max,i,j,k:

longint;

c:

array[0..51]oflongint;

f:

array[0..51,0..1001]ofboolean;

begin

assign(input,'changingsounds.in');

reset(input);

assign(output,'changingsounds.out');

rewrite(output);

read(n,b,max);

fori:

=1tondo

read(c[i]);

fillchar(f,sizeof(f),false);

f[0,b]:

=true;

fori:

=1tondo

forj:

=0tomaxdo

begin

if(0<=j-c[i])and(j-c[i]<=max)then

f[i,j]:

=f[i,j]orf[i-1,j-c[i]];

if(0<=j+c[i])and(j+c[i]<=max)then

f[i,j]:

=f[i,j]orf[i-1,j+c[i]];

end;

ans:

=-1;

fori:

=0tomaxdo

iff[n,i]then

ans:

=i;

writeln(ans);

close(input);

close(output);

End.

 

第二题外星人(alien)

神题……

考场上我不会做……

实际上是找规律……

发现规律就好很做了。

30分暴力模拟好了。

60分每次把质因数分解好了,100000以内的质因数不超过10000个。

Ac算法呢,首先要发现一个规律。

对于一个质因数p,等于2直接就消去了,大于2的时候,p-1肯定能被2整除,所以进行求一次欧拉函数之后,直到消完质因数都含有2,而且明显2的个数是最多的,每次还只会消去一个2,所以最后消去的一定是2。

那么,问题就变成了询问所有质因数消除的时候会产生多少个2。

因为p小于100000,可以预处理一下每个p分解会产生多少个2。

回答询问是回答2的个数,需要注意的是,如果一开始的质因数不含有2的话答案为2的个数加一。

代码:

programalien;

const

maxn=100000;

var

q,p,t,m,n,i,j,k:

longint;

ok:

boolean;

ans:

int64;

quick:

array[0..maxn]oflongint;

yes:

array[0..maxn]ofboolean;

begin

assign(input,'alien.in');

reset(input);

assign(output,'alien.out');

rewrite(output);

read(t);

quick[2]:

=1;

fori:

=3tomaxndo

ifnotyes[i]then

begin

k:

=i-1;

forj:

=2totrunc(sqrt(i-1))do

whilekmodj=0do

begin

quick[i]:

=quick[i]+quick[j];

k:

=kdivj;

end;

ifk>0then

quick[i]:

=quick[i]+quick[k];

forj:

=itomaxndivido

yes[i*j]:

=true;

end;

whilet>0do

begin

dec(t);

read(m);

ans:

=0;

ok:

=false;

fori:

=1tomdo

begin

read(p,q);

ifp=2thenok:

=true;

ans:

=ans+int64(quick[p])*q;

end;

ifnotoktheninc(ans);

writeln(ans);

end;

close(input);

close(output);

end.

 

第三题:

道路(road)

30分算法就是搜索。

求从一个点出发,到某个点的最短路个数是经典问题,用heap+dijkstra就可以解决。

设dis[i,j]表示i到j的最短距离,count[i,j]表示i到j的最短路径数目

若o是一条权值为w的u到v的有向边,那么若dis[i,u]+w+dis[v,j]=dis[i,j],那么从i到j的经过o的最短路数目为count[i,u]*count[v,j]

这样便得出了60分算法,预处理出来dis数组和count数组,枚举i、j和o,统计答案。

复杂度O(n^2m)

60分算法超时的问题在于枚举点对,如何能避免枚举点对呢?

容易想到直接计算一个点为起点到所有点最短路对答案的贡献,首先将边沿正向走一遍,求从原点到每个点的最短路径个数,然后按距离远点距离从大到小的顺序沿反向边来贡献答案。

这个我不说不清……理解了60分算法多想想还是能理解的。

代码:

programroad;

const

maxn=1000000007;

type

quick=array[0..1501]oflongint;

var

all,n,m,i,j,k,u,v,w,tot,o:

longint;

stu,count,root,roo:

array[0..1501]oflongint;

dis:

quick;

yes:

array[0..1501]ofboolean;

dl:

array[0..100001]oflongint;

ans,point,next,cost,poi,nex,cos:

array[0..5001]oflongint;

line:

array[0..5001]ofrecord

u,v,w:

longint;

end;

heap:

array[0..10001]oflongint;

procedureinsert(who:

longint);

var

i:

longint;

begin

yes[who]:

=true;

inc(tot);

heap[tot]:

=who;

i:

=tot;

while(i>1)and(dis[who]

begin

heap[i]:

=heap[idiv2];

heap[idiv2]:

=who;

i:

=idiv2;

end;

end;

proceduredelete;

var

i,k:

longint;

begin

yes[heap[1]]:

=false;

iftot=1then

begin

heap[1]:

=0;

dec(tot);

exit;

end;

heap[1]:

=heap[tot];

heap[tot]:

=0;

dec(tot);

i:

=1;

while(dis[heap[i*2]]

or(dis[heap[i*2+1]]

ifdis[heap[i*2]]

begin

k:

=heap[i];

heap[i]:

=heap[i*2];

heap[i*2]:

=k;

i:

=i*2;

end

else

begin

k:

=heap[i];

heap[i]:

=heap[i*2+1];

heap[i*2+1]:

=k;

i:

=i*2+1;

end;

end;

begin

assign(input,'road.in');

reset(input);

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

当前位置:首页 > 人文社科 > 法律资料

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

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