noip复赛模拟练习7答案.docx
《noip复赛模拟练习7答案.docx》由会员分享,可在线阅读,更多相关《noip复赛模拟练习7答案.docx(12页珍藏版)》请在冰豆网上搜索。
noip复赛模拟练习7答案
【问题描述】
对于给定的一个长度为N的正整数数列A[i],现要将其分成连续的若干段,并且每段和不超过M(可以等于M),问最少能将其分成多少段使得满足要求。
【输入文件】
输入文件divide_a.in的第1行包含两个正整数N,M,表示了数列A[i]的长度与每段和的最大值,第2行包含N个空格隔开的非负整数A[i],如题目所述。
【输出文件】
输出文件divide_a.out仅包含一个正整数,输出最少划分的段数。
【样例输入】
56
42451
【样例输出】
3
【数据规模与约定】
对于20%的数据,有N≤10;
对于40%的数据,有N≤1000;
对于100%的数据,有N≤100000,M≤109,M大于所有数的最小值,A[i]之和不超过109。
【样例说明】
将数列如下划分:
[4][24][51]
第一段和为4,第2段和为6,第3段和为6均满足和不超过M=6,并可以证明3是最少划分的段数。
var
n,m,t,i,a,ans:
longint;
begin
assign(input,'divide_a.in');
assign(output,'divide_a.out');
reset(input);rewrite(output);
readln(n,m);
t:
=0;ans:
=0;
fori:
=1tondobegin
read(a);
ift+a>mthenbegin
inc(ans);
t:
=a;
end
else
inc(t,a);
end;
ift<>0theninc(ans);
writeln(ans);
close(input);close(output);
end.
将合数483的各位数字相加(4+8+3)=15,如果将483分解成质因数相乘:
483=3*7*23,把这些质因数各位数字相加(3+7+2+3),其和也为15。
即某合数的各位数字之和等于它所有质因数的各数字之和。
求1-N之间具有上述特点的所有合数。
如输入N=100则输出42227588594
varn,t1,t2,tatol:
integer;
yes:
boolean;
proceduresub1(x:
integer;vart:
integer); {过程:
分离x的各位数字}
begin {并求各位数字之和}
repeat
t:
=t+xmod10;
x:
=xdiv10;
untilx=0
end;
proceduresub2(x:
integer;vart:
integer); {过程:
分解质因数}
varxx,tt:
integer;
begin
xx:
=2;
whilex>1do
ifxmodxx=0then
begin
tt:
=0;
sub1(xx,tt);
t:
=t+tt;
x:
=xdivxx
end
elseinc(xx)
end;
proceduresub3(x:
integer;varyy:
boolean); {过程:
判断x是否为素数}
vark,m:
integer;
begin
k:
=trunc(sqrt(x));
form:
=2tokdo
ifxmodm=0thenyy:
=false;
end;
begin {主程序}
forn:
=1to500do
begin
t1:
=0;t2:
=0;
yes:
=true;
sub3(n,yes); {调用过程求素数}
ifnotyesthen {如果非素数就…}
begin
sub1(n,t1); {调用过程求n的各位数字之和}
sub2(n,t2); {调用过程求n的各质因数的数字之和}
ift1=t2thenwrite(n:
6); {打印合格的合数}
end
end;
readln
end.
42227588594121166202265274319346355378382391438454483
木偶(PUPPET)
提交文件名:
PUPPET.PAS
问题描述:
有一种玩具,在玩具上有一个红色按钮,一个黄色按钮和一百个能坐能站的小木偶,按一次红色的按钮,就会有一个站着的小木偶坐下去,按一次黄色按钮,就可以使站着的小木偶增加一倍。
开始时有三个小木偶站着,要想使站着的小木偶增加到N个,最少按几次按钮就行了?
每一次按哪个按钮?
问题求解:
请编一程序,由键盘输入N(1≤N≤100),输出由1(按红色按钮)和2(按黄色按钮)组成的按钮次序及总次数。
输入输出示例:
N=21
PRESSSEQUENCE:
22121
PRESSTIMES:
5
var
s:
string;
n:
longint;
begin
write('N=');
readln(n);
s:
='';
ifn>3then
repeat
ifodd(n)
thenbegin
s:
='1'+s;n:
=n+1;
end
elsebegin
s:
='2'+s;n:
=ndiv2;
end;
untiln<=3;
ifn=2thens:
='1'+s;
ifn=1thens:
='11'+s;
writeln('PRESSSEQUENCE:
',S);
writeln('PRESSTIMES:
',length(s));
readln;
end.
5(212)100(122121212210)30(1222126)
直接解密(IMMEDIATEDECODABILITY)
提交文件名:
IMME.PAS
问题描述:
一个01串的集合,元素两两均不相同。
如果任意个元素都不是其它元素的前缀,那么这个集合就被称为可直接解密的。
我们规定01串的长度从1到50,每个集合中的01串个数从2到20个。
例如:
01
10
0010
0000
这个4个元素的01串集合就满足条件,是可直接解密的。
但
01
10
010
0000
不是,因为01是010的前缀。
输入文件(IMME.IN):
有若干行,每行一个01串,以一行“#”为结束标志。
输出文件(IMME.OUT):
如果这个集合是可直接解密的,输出“immediatelydecodable”;
否则,输出“notimmediatelydecodable”。
输入输出样例:
IMME.IN
01
10
0010
0000
#
IMME.OUT
Immediatelydecodable
var
s:
array[1..21]ofstring[50];
i,j,n:
integer;
b:
boolean;
begin
writeln('Input:
');
n:
=0;
repeat
inc(n);
readln(s[n]);
ifs[n]='#'thenbreak;
untilfalse;
dec(n);
b:
=true;
fori:
=1tondobegin
forj:
=1tondo
if(i<>j)and(pos(s[i],s[j])=1)thenbegin
b:
=false;break;
end;
ifnotbthenbreak;
end;
writeln('Output:
');
ifbthenwriteln('immediatelydecodable')
elsewriteln('notimmediatelydecodable');
readln;
end.
球星罗纳梅尔多最近被聘为C城城市形象代言人,巨幅照片被贴在每一条道路旁,可是就是这些照片,造成了司机看了海报、照片之后心脏病突发,引发了交通事故,所以C城的交通经常处于混乱状态。
C城交通部长里瓦梅尔多是罗纳梅尔多的好友,他当然不忍心取缔好友的广告牌。
于是,他为了便于管理,准备在C城安装一个交通系统,通过该系统显示该城哪些道路处于混乱堵车状态。
C城有n个交通路口,任意两个交通路口之间都有一条双向的路。
假设系统是从上午8点开始运行,此时所有看了罗纳梅尔多照片的人都晕倒了,此时所有的道路都处于堵车状态。
如果一条道路处于堵车状态,那么这条道路连接的两个路口将不能通过这一条边互达。
系统需要即时处理三个问题:
1,Iuv道路(u,v)被疏通了,此时两路口u,v可以通过这条道路互达。
2,Duv道路(u,v)又堵车了,此时两路口不能通过这条道路互达。
3,Quv回答出两路口u,v是否可以互相到达(直接或间接都可以)。
而你被里瓦梅尔多雇佣编写这个交通系统,至于报酬嘛,就是请你当任该系统的形象代言人。
J
输入描述:
第一行两个整数n,m,分别表示城市的路口以及需要系统处理的问题数。
接下来m行,每行一条指令,格式见样例。
输出描述:
对于每个Q询问,如果两路口可以互达则输出Y否则输出N。
输入样例:
35
I12
I23
Q13
D12
Q13
输出样例:
Y
N
数据范围:
n<=100;m<=40000
注意:
对于某条道路(u,v),其瘫痪与否的状态总是交替改变的。
解法:
水题,对于每次询问,只要把能和v相通的路口求出来看有没有q就行了。
代码:
var
n,m,v,q,i:
longint;
a,p:
char;
s:
array[0..101]ofboolean;
f:
array[0..101,0..101]ofboolean;
proceduredfs(dep:
longint);
var
i:
longint;
begin
ifs[q]thenexit;
fori:
=1tondoif(nots[i])and(f[i,dep])thenbegin
s[i]:
=true;
dfs(i);
end;
end;
begin
readln(n,m);
fori:
=1tomdobegin
read(a,p);
readln(v,q);
ifa='I'thenbegin
f[v,q]:
=true;
f[q,v]:
=true;
endelseifa='D'thenbegin
f[v,q]:
=false;
f[q,v]:
=false;
endelsebegin
s[v]:
=true;
dfs(v);
ifs[q]thenwriteln('Y')elsewriteln('N');
fillchar(s,sizeof(s),false);
end;
end;
end.
水王争霸
【描述】
众所周知,IOIForum有很多水王,他们的发贴数是如此之多,以至于必须要用高精度数才能保存。
为了迎接国庆,IOIForum决定举行一次水王争霸赛,比赛的规则是将这些水王截止到2003年9月30日23时59分59秒这一刻所发的总贴数从大到小进行排序。
每个水王当然都想取得尽量靠前的名次,所以他们竭尽全力,不择手段地进行灌水。
终于,激动人心的一刻到来了,2003年10月1日0时0分0秒,你作为裁判得到了每个水王的发贴数,现在,你的任务是公正地把这些水王按照发贴数从大到小进行排序。
【输入格式】
输入一个1到1000的整数N,表示总共有N位水王参加了争霸赛。
以下依次给出每位水王的描述,一个仅由字母和数字组成的长度不超过20的字符串,代表这个水王的ID,一个高精度的整数(非负数),代表这个水王的发贴数。
注意,这个整数的首位没有不必要的0。
考虑到IOIForum的数据库是有限的,所有水王发贴数的总长度(注意,是总长度而不是总和)不会超过10000。
除了子母、数字和必要的换行,输入中不会出现空格等字符。
【输出格式】
依次输出按照发贴数从大到小排好序的各位水王的ID,每个ID占据单独的一行。
不能有任何多余的字符。
若几个ID的发贴数相同,则按照ID的字典顺序先后排列。
【输入样例】:
2lowai153********61243453zhouyuan23453265344
【输入样例】:
lowaizhouyuan
解法:
这道题由于n较小所以直接用冒泡。
难点在于判断帖数与字符串的大小。
帖数的比较就不说了,字符串的比较稍微提一下:
比较字符串是按照字符串中的字符一个个比较的只要一个字符不相同那么就停止比较得出结果(哪个字符小该字符串就更小)如果一个字符串是另一个的前m位,那么这个字符串更小
代码:
var
i,n,j:
longint;
a:
array[0..1001]ofstring;
b:
array[0..1001]ofansistring;
functionzb(a,b:
string):
boolean;
var
i,len,len2:
longint;
begin
len:
=length(a);
len2:
=length(b);
iflen>len2thenbegin
fori:
=1tolen2dobegin
ifa[i]
ifb[i]end;
exit(false);
endelsebegin
fori:
=1tolendobegin
ifa[i]
ifb[i]end;
exit(true);
end;
end;
functionca(a,b:
ansistring):
integer;
var
i:
longint;
begin
iflength(a)>length(b)thenexit
(1);
iflength(b)>length(a)thenexit
(2);
fori:
=1tolength(a)dobegin
ifa[i]>b[i]thenexit
(1);
ifb[i]>a[i]thenexit
(2);
end;
exit(0);
end;
begin
readln(n);
fori:
=1tondobegin
readln(a[i]);
readln(b[i]);
end;
fori:
=1ton-1doforj:
=i+1tondoifca(b[i],b[j])=2thenbegin
a[0]:
=a[i];
a[i]:
=a[j];
a[j]:
=a[0];
b[0]:
=b[i];
b[i]:
=b[j];
b[j]:
=b[0];
endelseif(ca(b[i],b[j])=0)and(notzb(a[i],a[j]))thenbegin
a[0]:
=a[i];
a[i]:
=a[j];
a[j]:
=a[0];
b[0]:
=b[i];
b[i]:
=b[j];
b[j]:
=b[0];
end;
fori:
=1tondowriteln(a[i]);
end.