主题:[讨论]征集NOIP 2007提高组复赛程序
网络笑侠
[专家分:30] 发布于 2007-11-17 11:50:00
如题
大家发上来讨论一下
我不太会
哪位大牛能把程序发上来,给我讲讲
回复列表 (共7个回复)
沙发
网络笑侠 [专家分:30] 发布于 2007-11-17 13:58:00
怎么没人?
大家都没回来?
板凳
abcwuhang [专家分:1840] 发布于 2007-11-18 17:46:00
甚么试题??
麻烦帖以下
3 楼
shisutianxia [专家分:630] 发布于 2007-11-25 09:04:00
最后一题我的解法
program core;
type ss=array[0..100]of 0..100;
var a:array[1..100,1..100]of integer;
v:array[1..100]of 0..1;
rec,daan:ss;
prec:array[1..100]of ss;
m,o,b,c,d,kw,t,n,s,i,j:integer;zhi,p,q:longint;flag:boolean;
procedure panduan;
var j,i:integer;
begin
for i:=1 to o do
begin flag:=true;
for j:=1 to prec[i][0] do
if daan[j]<>prec[i][daan[0]-j+2] then begin flag:=false;break;end;
if flag=true then break;
end;
end;
procedure search(k:longint);
var l,i,j:integer;
begin
for i:=1 to n do
if (v[i]=0)and(a[i,rec[t]]<>0) then begin
v[i]:=1;inc(t);rec[t]:=i;k:=k+a[i,rec[t-1]];
if k>kw then begin
for j:=1 to t do
daan[j]:=rec[j];
daan[0]:=t;kw:=k;
end;
search(k);
end;
v[t]:=0;
t:=t-1;
end;
function count(d,b:integer):longint;
var k,i:integer;
begin
k:=0;
for i:=d+1 to b do
k:=k+a[prec[o][i-1],prec[o][i]];
count:=k;
end;
begin
readln(n,s);
for i:=1 to 100 do
for j:=1 to 100 do
begin
a[i,j]:=0;
prec[i][j]:=0;;
end;
for i:=1 to n-1 do
begin
readln(b,c,d);
a[b,c]:=d;a[c,b]:=d;
end;
for i:=1 to n do
begin
for j:=1 to n do
write(a[i,j]:3);
writeln;
end;
fillchar(v,sizeof(v),0);
fillchar(rec,sizeof(rec),0);
fillchar(daan,sizeof(daan),0);
p:=0;o:=0;
for i:=1 to n do
begin
v[i]:=1;t:=1;
rec[t]:=i;
kw:=0;
search(kw);
if kw>p then begin
p:=kw;o:=1;
for j:=0 to daan[0] do
prec[o][j]:=daan[j];
end;
if kw=p then begin
panduan;
if flag=false then begin
inc(o);
for j:=0 to daan[0] do
prec[o][j]:=daan[j];
end;
end;
v[i]:=0;
end;
for i:=1 to o do
begin
for j:=1 to prec[o][0] do
write(prec[o][j]);
writeln;
end;
q:=maxint;
for i:=1 to o do
for j:=1 to prec[o][0] do
for m:=j to prec[o][0] do
begin
if count(j,m)>=s then break;
if count(1,j)>count(m,prec[o][0]) then
zhi:=count(1,j)
else zhi:=count(m,prec[o][0]);
if zhi<q then q:=zhi;
end;
writeln(q);
end.
4 楼
shisutianxia [专家分:630] 发布于 2007-11-25 10:38:00
我的EXPAND.PAS
program expand;
var i,j,re,p1,p2,p3:integer;
st:string;ch:char;
procedure shuchu(a,b:char);
var i:char;j:integer;
begin
if p1=3 then
for i:=succ(a) to pred(b) do
for j:=1 to p2 do
write('*')
else begin
if p3=1then for i:=succ(a) to pred(b) do
for j:=1 to p2 do
write(i);
if p3=2 then for i:=pred(b) downto succ(a) do
for j:=1 to p2 do
write(i);
end;
end;
begin
readln(p1,p2,p3);
readln(st);
for i:=1 to length(st) do
begin
if st[i]<>'-'then write(st[i])
else begin
if st[i-1]>=st[i+1]then write('-')
else
if st[i-1] in['0'..'9'] then shuchu(st[i-1],st[i+1])
else
begin
if p1=2 then shuchu(chr(ord(st[i-1])+ord('A')-ord('a')),chr(ord(st[i+1])+ord('A')-ord('a')));
if p1=2 then shuchu(st[i-1],st[i+1]);
end;
end;
end;
end.
5 楼
风吻sky [专家分:0] 发布于 2007-11-25 11:15:00
2007年赣州市青少年计算机奥林匹克竞赛上机试题
(高中组)
县市 学校 姓名 成绩
注:第1题至第4题任选两题做,第5题至第7题为必做题。
第1题:最长单词输出(15分)
编写一个程序,输入一行字符串,将此字符串中的最长的单词输出。若有两个单词长度一样,且是最长,则输出更大的这个单词(按ASCII码比较大小)。
输入输出样例:
样例1:输入:I am a teacher
输出:teacher
样例2:输入:How are you
输出: you
第2题:编程求平方根(15分)
任给常数b,编程求 ,要求准确到小数点后3位,注意不能调用高级语言系统的开平方根函数。
输入输出样例:输入:b=7
输出:2.646
第3题:找猴王(15分)
编写m只猴子选大王的程序:所有的猴子按1,2,3,…,m编号,围坐一圈,按1,2,3,…,n报数,报到n的猴子出列,直到圈内剩下一只猴子时,这只猴子就是大王。要求:
(1) m,n由键盘输入;
(2) 输出猴王的号码。
输入输出样例:输入:6, 3 (表示:m=6,n=3)
输出:1 (表示编号为1的猴子是猴王)
第4题:芝麻开门 ( 15分)
周末小可可参加智力大冲浪活动,经过努力终于来到最后一关“芝麻开门”。门上的电子显示屏写着这么一段话:如果你能把nk的所有正整数因子的和正确地写列门上,并念一声“芝麻开门”,门就能够自动打开。
例如,n=2、k=2,则nk=4,它的正整数因子有1, 2, 4,如果小可可把7(即1+2+4=7)写到门上然后念一声“芝麻开门”,门就能够自动打开。
已知门上的n、k都是每过一段时间就会变化一次,请你编写程序协助小可可在规定的时间内求出答案,从而获得智力大冲浪的最终大奖。
输入:文件中以一行的形式存放了两个自然数n和k,1≤n<216,1≤k<20
输出:以一行的形式输出问题的解 (解的位数不超过100位)。
输入输出样例:(1) 输入:1 1
输出:1
(2) 输入:2 2
输出:7
第5题:滑雪(共20分)
Michael喜欢滑雪。这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必需向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道在一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。
下面是一个例子:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
一个人可以从某个点不滑向上下左右相邻四个点之一,当且仅当高度减小,在上面的例子中,一条可行的不滑坡为24-17-16-1(从24开始,在1结束)。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。
输入输出要求:
输入的第1行为表示区域的二维数组的行数R和列数C(1≤R,C≥100)。下面是R行,每行有C个数,代表高度。
输出区域中最长滑坡的长度。
输入输出样例:
输 入 输 出
5 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9 25
第6题:网络传输 ( 25分)
在计算机网络中所有数据网络传输都是以二进制形式来传输的。但是在进行较大数据的传输时,直接使用该数的二进制形式加以传输则往往传输的位数过多。譬如要住输1024就需要11位二进制数。于是小可可提出了一种数据优化传输的设想,并打算对这一设想进行试验。
该设想是:正整数k的所有方幂以及任意多个互不相等的k的方幂之和排成一个递增数列和{a(k)n},例如当k=3时,和{a(k)n}的前7项为1(即30). 3(即31)、4(即30+31)、9(即32)、10(即30+32)、12(即31+32)、13(即30+31+32)。如果数d是数列和{a(k)n}中的第p项,则可以通过传送k和p这两个数来表示数d。由于k和p这两个相对很小的数就可以表达出很大的数d,因而理论上可以减少网络传输的位数。
小可可现在请你编写程序把接收到的数k和p所代表的数d计算出来。
输入:文件中以一行的形式存放了两个正整数k和p,1<k≤1024,1≤p≤1024。
输出:以一行的形式输出问题的解 (解的位数不超过50位)。
输入输出样例:(1) 输入:3 2 (即 k=3,p=2)
输出:3 (即 d=3 )
(2) 输入:3 7
输出:13
第7题:架设桥梁(共25分)
在未来的空中都市中,有很多小岛(城区),现在要求在这些小岛之间架一些桥梁,每座桥是指在两个岛之间的通道。有个约定,如果A和B之间有桥,B与C之间有桥,则A与C之间就不能再有桥了,即对于城市中的任意三个岛,不能在其中的两两之间都架上桥。在这样的约定下,要求架的桥的数量最多,当然不必考虑具体的空间结构问题。
输入输出要求:
输入文件中只包含一行,其中仅有n,0≤n≤1000,表示小岛的数量。
输出文件中只包含一行,表示最多能架设的桥梁的数量。
输入输出示例:输入:6
输出:9
6 楼
风吻sky [专家分:0] 发布于 2007-11-25 11:16:00
啊,错了。是
全国信息学奥林匹克联赛(NOIP2007)复赛(提高组)
2007年11月22日 下午 03:38全国信息学奥林匹克联赛(NOIP2007)复赛
提高组
题目一览
题目名称
统计数字
字符串的展开
矩阵取数游戏
树网的核
代号
count
expand
game
core
输入文件
count.in
expand.in
game.in
core.in
输出文件
count.out
expand.out
game.out
core.out
时限
1秒
1秒
1秒
1秒
(2007年11月17日 3小时完成)
说明:
1. 文件名(程序名和输入输出文件名)必须使用小写
2. C/C++中函数main()的返回值必须是int,程序正常结束时返回值必须是0。
3. 全国统一评测时采用的机器参考配置为:CPU 2.0GHz,内存256M。
1. 统计数字
(count.pas/c/cpp)
【问题描述】
某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。
【输入】
输入文件count.in包含n+1行;
第一行是整数n,表示自然数的个数;
第2~n+1每行一个自然数。
【输出】
输出文件count.out包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。
【输入输出样例】
count.in
count.out
8
2
4
2
4
5
100
2
100
2 3
4 2
5 1
100 2
【限制】
40%的数据满足:1<=n<=1000
80%的数据满足:1<=n<=50000
100%的数据满足:1<=n<=200000,每个数均不超过1500 000 000(1.5*109)
2. 字符串的展开
(expand.pas/c/cpp)
【问题描述】
在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或者“4-8”的字串,我们就把它当作一种简写,输出时,用连续递增的字母获数字串替代其中的减号,即,将上面两个子串分别输出为“defgh”和“45678”。在本题中,我们通过增加一些参数的设置,使字符串的展开更为灵活。具体约定如下:
(1) 遇到下面的情况需要做字符串的展开:在输入的字符串中,出现了减号“-”,减号两侧同为小写字母或同为数字,且按照ASCII码的顺序,减号右边的字符严格大于左边的字符。
(2) 参数p1:展开方式。p1=1时,对于字母子串,填充小写字母;p1=2时,对于字母子串,填充大写字母。这两种情况下数字子串的填充方式相同。p1=3时,不论是字母子串还是数字字串,都用与要填充的字母个数相同的星号“*”来填充。
(3) 参数p2:填充字符的重复个数。p2=k表示同一个字符要连续填充k个。例如,当p2=3时,子串“d-h”应扩展为“deeefffgggh”。减号两边的字符不变。
(4) 参数p3:是否改为逆序:p3=1表示维持原来顺序,p3=2表示采用逆序输出,注意这时候仍然不包括减号两端的字符。例如当p1=1、p2=2、p3=2时,子串“d-h”应扩展为“dggffeeh”。
(5) 如果减号右边的字符恰好是左边字符的后继,只删除中间的减号,例如:“d-e”应输出为“de”,“3-4”应输出为“34”。如果减号右边的字符按照ASCII码的顺序小于或等于左边字符,输出时,要保留中间的减号,例如:“d-d”应输出为“d-d”,“3-1”应输出为“3-1”。
【输入】
输入文件expand.in包括两行:
第1行为用空格隔开的3个正整数,一次表示参数p1,p2,p3。
第2行为一行字符串,仅由数字、小写字母和减号“-”组成。行首和行末均无空格。
【输出】
输出文件expand.out只有一行,为展开后的字符串。
【输入输出样例1】
expand.in
expand.out
1 2 1
abcs-w1234-9s-4zz
abcsttuuvvw1234556677889s-4zz
【输入输出样例2】
expand.in
expand.out
2 3 2
a-d-d
aCCCBBBd-d
【输入输出样例3】
expand.in
expand.out
3 4 2
di-jkstra2-6
dijkstra2************6
【限制】
40%的数据满足:字符串长度不超过5
100%的数据满足:1<=p1<=3,1<=p2<=8,1<=p3<=2。字符串长度不超过100
类别:信息技术奥赛相关 | 添加到搜藏 | 浏览(39) | 评论 (0) 3. 矩阵取数游戏
(game.pas/c/cpp)
【问题描述】
帅帅经常更同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij据为非负整数。游戏规则如下:
1. 每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有的元素;
2. 每次取走的各个元素只能是该元素所在行的行首或行尾;
3. 每次取数都有一个得分值,为每行取数的得分之和;每行取数的得分 = 被取走的元素值*2i,其中i表示第i次取数(从1开始编号);
4. 游戏结束总得分为m次取数得分之和。
帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。
【输入】
输入文件game.in包括n+1行;
第一行为两个用空格隔开的整数n和m。
第2~n+1行为n*m矩阵,其中每行有m个用单个空格隔开
【输出】
输出文件game.out仅包含1行,为一个整数,即输入矩阵取数后的最大的分。
【输入输出样例1】
game.in
game.out
2 3
1 2 4
3 4 2
82
【输入输出样例1解释】
第1次:第一行取行首元素,第二行取行尾元素,本次的氛围1*21+2*21=6
第2次:两行均取行首元素,本次得分为2*22+3*22=20
第3次:得分为3*23+4*23=56。总得分为6+20+56=82
【输入输出样例2】
game.in
game.out
1 4
4 5 0 5
122
【输入输出样例3】
game.in
game.out
2 10
96 56 54 46 86 12 23 88 80 43
16 95 18 29 30 53 88 83 64 67
316994
【限制】
60%的数据满足:1<=n, m<=30,答案不超过1016
100%的数据满足:1<=n, m<=80,0<=aij<=1000
4. 树网的核
(core.pas/c/cpp)
【问题描述】
设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并设T有n个结点。
路径:树网中任何两结点a,b都存在唯一的一条简单路径,用d(a, b)表示以a, b为端点的路径的长度,它是该路径上各边长度之和。我们称d(a, b)为a, b两结点间的距离。
D(v, P)=min{d(v, u), u为路径P上的结点}。
树网的直径:树网中最长的路径成为树网的直径。对于给定的树网T,直径不一定是唯一的,但可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。
偏心距ECC(F):树网T中距路径F最远的结点到路径F的距离,即
ECC(F)=max{d(v, F),v∈V}
任务:对于给定的树网T=(V, E, W)和非负整数s,求一个路径F,他是某直径上的一段路径(该路径两端均为树网中的结点),其长度不超过s(可以等于s),使偏心距ECC(F)最小。我们称这个路径为树网T=(V, E, W)的核(Core)。必要时,F可以退化为某个结点。一般来说,在上述定义下,核不一定只有一个,但最小偏心距是唯一的。
下面的图给出了树网的一个实例。图中,A-B与A-C是两条直径,长度均为20。点W是树网的中心,EF边的长度为5。如果指定s=11,则树网的核为路径DEFG(也可以取为路径DEF),偏心距为8。如果指定s=0(或s=1、s=2),则树网的核为结点F,偏心距为12。
【输入】
输入文件core.in包含n行:
第1行,两个正整数n和s,中间用一个空格隔开。其中n为树网结点的个数,s为树网的核的长度的上界。设结点编号以此为1,2,……,n。
从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。
所给的数据都是争取的,不必检验。
【输出】
输出文件core.out只有一个非负整数,为指定意义下的最小偏心距。
【输入输出样例】
【输入输出样例1】
core.in
Core.out
5 2
1 2 5
2 3 2
2 4 4
2 5 3
5
【输入输出样例2】
core.in
core.out
8 6
1 3 2
2 3 2
3 4 6
4 5 3
4 6 4
4 7 2
7 8 3
5
【限制】
40%的数据满足:5<=n<=15
70%的数据满足:5<=n<=80
100%的数据满足:5<=n<=300,0<=s<=1000。边长度为不超过1000的正整数
类别:信息技术奥赛相关 | 添加到搜藏 | 浏览(24) | 评论 (1)
7 楼
shisutianxia [专家分:630] 发布于 2007-11-25 16:54:00
GAME.PAS(具体运行过程有相关提示,有更好办法告诉我,谢谢)
program game;
type ss=record
st,en:integer;
a:array[1..81]of integer;
end;
ty=array[0..30]of 0..9;
var rec:array[1..81] of ss;
l,m,n,re,num,i,j:integer;daan,mid:ty;
procedure add(var a,b:ty);
var p,i,j:integer;c:ty;
begin
if a[0]>b[0] then begin
p:=0;c[0]:=a[0];
for i:=1 to a[0] do
begin
c[i]:=(a[i]+b[i]+p)mod 10;
p:=(a[i]+b[i]+p)div 10;
end;
end
else begin
p:=0;c[0]:=b[0];
for i:=1 to b[0] do
begin
c[i]:=(a[i]+b[i]+p)mod 10;
p:=(a[i]+b[i]+p)div 10;
end;
end;
if p>0 then begin inc(c[0]);c[c[0]]:=p;end;
for i:=0 to c[0] do
a[i]:=c[i];
writeln('=');
end;
procedure chen(var a:ty;x:integer);
var i,p,q:longint;
begin
p:=0;q:=0;
for i:=1 to a[0] do
begin
q:=(a[i]*x+p)div 10;
a[i]:=(a[i]*x+p)mod 10;
p:=q;
end;
while p<>0 do
begin
inc(a[0]);
a[a[0]]:=p mod 10;
p:=p div 10;
end;
end;
begin
readln(n,m);
fillchar(rec,sizeof(rec),0);
fillchar(daan,sizeof(daan),0);
daan[0]:=1;daan[1]:=0;
for i:=1 to n do
begin
for j:=1 to m do
read(rec[i].a[j]);
rec[i].st:=1;
rec[i].en:=m;
readln;
end;
for i:=1 to n do
begin
for j:=1 to m do
write(rec[i].a[j]);
writeln;
end;
for j:=1 to m do
for i:=1 to n do
begin
fillchar(mid,sizeof(mid),0);
mid[0]:=1;
mid[1]:=1;
writeln('bijiao',rec[i].a[rec[i].st],'--',rec[i].a[rec[i].en]);
if rec[i].a[rec[i].st]<rec[i].a[rec[i].en] then
begin
for re:=1 to j do
chen(mid,2);
chen(mid,rec[i].a[rec[i].st]);
inc(rec[i].st);
end
else begin
for re:=1 to j do
chen(mid,2);
chen(mid,rec[i].a[rec[i].en]);
dec(rec[i].en);
end;
for l:=mid[0] downto 1 do
write('(',mid[l]);writeln;
add(daan,mid);for l:=daan[0]to 1 do write('#',daan[l]);readln;
end;
for i:=daan[0] downto 1 do
write(daan[i]);
writeln;
end.
我来回复