第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx

上传人:b****6 文档编号:17260843 上传时间:2022-11-29 格式:DOCX 页数:16 大小:21.49KB
下载 相关 举报
第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx_第1页
第1页 / 共16页
第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx_第2页
第2页 / 共16页
第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx_第3页
第3页 / 共16页
第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx_第4页
第4页 / 共16页
第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx

《第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。

第十一届全国青少年信息学奥林匹克联赛复赛提高组解题报告Word文档下载推荐.docx

模拟

【算法分析】

其中涉及简单的字符处理,特别要注意数据类型的应用。

如:

学生姓名可采用char和string相结合的方法处理,奖学金金额用longint较为适宜。

【程序】

programscholar;

varname:

array[1..100]ofstring;

a1,a2,a5:

array[1..100]oflongint;

a3,a4:

array[1..100]ofchar;

n,i,max,total,p:

longint;

maxname:

string;

ch:

char;

f:

text;

begin

assign(f,'

scholar.in'

);

reset(f);

readln(f,n);

fori:

=1tondo

begin

read(f,ch);

whilech<

>

'

'

do

name[i]:

=name[i]+ch;

end;

readln(f,a1[i],a2[i],ch,a3[i],ch,a4[i],ch,a5[i]);

close(f);

p:

=0;

if(a1[i]>

80)and(a5[i]>

=1)theninc(p,8000);

85)and(a2[i]>

80)theninc(p,4000);

90)theninc(p,2000);

85)and(a4[i]='

Y'

)theninc(p,1000);

if(a2[i]>

80)and(a3[i]='

)theninc(p,850);

ifp>

maxthen

max:

=p;

=name[i];

inc(total,p);

scholar.out'

rewrite(f);

writeln(f,maxname);

writeln(f,max);

writeln(f,total);

end.

 

题二过河

在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。

在桥上有一些石子,青蛙很讨厌踩在这些石子上。

由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:

0,1,……,L(其中L是桥的长度)。

坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。

青蛙从桥的起点开始,不停的向终点方向跳跃。

一次跳跃的距离是S到T之间的任意正整数(包括S,T)。

当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。

题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。

你的任务是确定青蛙要想过河,最少需要踩到的石子数。

输入文件river.in的第一行有一个正整数L(1<

=L<

=109),表示独木桥的长度。

第二行有三个正整数S,T,M,分别表示青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数,其中1<

=S<

=T<

=10,1<

=M<

=100。

第三行有M个不同的正整数分别表示这M个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。

所有相邻的整数之间用一个空格隔开。

输出文件river.out只包括一个整数,表示青蛙过河最少需要踩到的石子数。

10

235

23567

2

【数据规模】

对于30%的数据,L<

=10000;

对于全部的数据,L<

=109。

在一条长为L数轴上有若干障碍点,每次前进距离为S到T之间的任意正整数(包括S,T),求走过L或大于L的距离,遇到最少的障碍点。

看到题目首先想到的是时间复杂度为O(L)的递推算法。

但是L的上限为10^9,这种算法显然是不行的。

仔细思考,可以得到下面的结论:

存在N0,当n>

N0时,n可以由若干S到T之间的正整数(包括S,T)组成。

因此,将障碍点按升序排列,当两相邻障碍点之间距离较大时,可适当缩小两障碍点之间距离,但不影响最终结果。

根据上述结论,改进递推算法。

由于障碍点之间距离大大缩减,算法的复杂度是可以承受的。

特别地,当S=T时需要单独处理。

programriver;

constmax=105;

vara,a1:

array[0..101]oflongint;

b:

array[0..100]ofboolean;

c,d:

array[0..10000]oflongint;

l,s,t,m,ans,low,i,j,k,temp:

flag:

boolean;

procedureinit;

river9.in'

readln(f,l);

readln(f,s,t,m);

=1tomdoread(f,a[i]);

a[0]:

a[m+1]:

=l;

=1tom-1do

forj:

=i+1tomdo

ifa[i]>

a[j]then

temp:

=a[i];

a[i]:

=a[j];

a[j]:

=temp;

end;

procedurework1;

=1tomdo

ifa[i]mods=0theninc(ans);

procedurework2;

fillchar(b,sizeof(b),false);

b[0]:

=true;

=stotdo

=0to100do

ifb[j]then

k:

=1;

whilek*i+j<

=100do

b[k*i+j]:

inc(k);

=1to100do

=0tot-1do

ifnotb[i+j]thenbeginflag:

=false;

break;

ifflagthen

low:

=i;

break;

iflow<

tthenlow:

=t;

=1tom+1do

a1[i]:

=(a[i]-a[i-1]-low)modlow+a1[i-1]+low;

a:

=a1;

=1tomdod[a[i]]:

l:

=a[m+1];

=1tol+t-1doc[i]:

=max;

=1tol+t-1do

if(i-j>

=0)and(c[i]>

c[i-j]+d[i])then

c[i]:

=c[i-j]+d[i];

ans:

=ltol+t-1do

ifans>

c[i]thenans:

=c[i];

init;

ifs=tthenwork1

elsework2;

river.out'

writeln(f,ans);

题三篝火晚会

佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”。

在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会。

一共有n个同学,编号从1到n。

一开始,同学们按照1,2,……,n的顺序坐成一圈,而实际上每个人都有两个最希望相邻的同学。

如何下命令调整同学的次序,形成新的一个圈,使之符合同学们的意愿,成为摆在佳佳面前的一大难题。

佳佳可向同学们下达命令,每一个命令的形式如下:

(b1,b2,...bm-1,bm)

这里m的值是由佳佳决定的,每次命令m的值都可以不同。

这个命令的作用是移动编号是b1,b2,……bm–1,bm的这m个同学的位置。

要求b1换到b2的位置上,b2换到b3的位置上,……,要求bm换到b1的位置上。

执行每个命令都需要一些代价。

我们假定如果一个命令要移动m个人的位置,那么这个命令的代价就是m。

我们需要佳佳用最少的总代价实现同学们的意愿,你能帮助佳佳吗?

输入文件fire.in的第一行是一个整数n(3<

=n<

=50000),表示一共有n个同学。

其后n行每行包括两个不同的正整数,以一个空格隔开,分别表示编号是1的同学最希望相邻的两个同学的编号,编号是2的同学最希望相邻的两个同学的编号,……,编号是n的同学最希望相邻的两个同学的编号。

输出文件fire.out包括一行,这一行只包含一个整数,为最小的总代价。

如果无论怎么调整都不能符合每个同学的愿望,则输出-1。

34

43

12

对于30%的数据,n<

=1000;

对于全部的数据,n<

=50000。

根据一定的移动规则,将初始圆环转化为满足一定条件的目标圆环。

从第一个人处断开,将圆环的问题转化为序列的问题。

如果可以,求出目标序列。

求出目标序列复杂度O(n).

求出目标序列右移0至n-1位置时,不需要移动的人数。

将目标序列反转,再求出目标序列右移0至n-1位置时,不需要移动的人数。

不需要移动的人数最大等价于需要移动的人数最小。

复杂度O(n)。

programfire;

vara:

array[1..50000]oflongint;

array[1..50000,1..2]oflongint;

d:

w:

array[0..50000]oflongint;

n,ans,i,j,t,max:

fire.in'

readln(f,b[i,1],b[i,2]);

inc(d[b[i,1]]);

inc(d[b[i,2]]);

ifd[i]<

2thenbeginflag:

exit;

procedurecircle;

a[1]:

a[2]:

=b[1,1];

=3tondo

ifb[a[i-1],1]<

a[i-2]thena[i]:

=b[a[i-1],1]

elsea[i]:

=b[a[i-1],2];

ifa[n]<

b[1,2]thenflag:

proceduremin;

fillchar(w,sizeof(w),0);

inc(w[(a[i]-i+n)modn]);

=0ton-1do

ifmax<

w[i]thenmax:

=w[i];

=1to(n+1)div2do

t:

=a[n+1-i];

a[n+1-i]:

=n-max;

ifflagthencircle;

ifflagthenmin;

fire.out'

ifflagthenwriteln(f,ans)elsewriteln(f,-1);

题四等价表达式

明明进了中学之后,学到了代数表达式。

有一天,他碰到一个很麻烦的选择题。

这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。

这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。

假设你是明明,能完成这个任务吗?

这个选择题中的每个表达式都满足下面的性质:

1.表达式只可能包含一个变量‘a’。

2.表达式中出现的数都是正整数,而且都小于10000。

3.表达式中可以包括四种运算‘+’(加),‘-’(减),‘*’(乘),‘^’(乘幂),以及小括号‘(’,‘)’。

小括号的优先级最高,其次是‘^’,然后是‘*’,最后是‘+’和‘-’。

‘+’和‘-’的优先级是相同的。

相同优先级的运算从左到右进行。

(注意:

运算符‘+’,‘-’,‘*’,‘^’以及小括号‘(’,‘)’都是英文字符)

4.幂指数只可能是1到10之间的正整数(包括1和10)。

5.表达式内部,头部或者尾部都可能有一些多余的空格。

下面是一些合理的表达式的例子:

((a^1)^2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1+(a-1)^3,1^10^9……

输入文件equal.in的第一行给出的是题干中的表达式。

第二行是一个整数n(2<

=26),表示选项的个数。

后面n行,每行包括一个选项中的表达式。

这n个选项的标号分别是A,B,C,D……

输入中的表达式的长度都不超过50个字符,而且保证选项中总有表达式和题干中的表达式是等价的。

输出文件equal.out包括一行,这一行包括一系列选项的标号,表示哪些选项是和题干中的表达式等价的。

选项的标号按照字母顺序排列,而且之间没有空格。

(a+1)^2

3

(a-1)^2+4*a

a+1+a

a^2+2*a*1+1^2+10-10+a-a

AC

对于30%的数据,表达式中只可能出现两种运算符‘+’和‘-’;

对于其它的数据,四种运算符‘+’,‘-’,‘*’,‘^’在表达式中都可能出现。

对于全部的数据,表达式中都可能出现小括号‘(’和‘)’。

判断两表达式是否等价。

用栈的方法求表达式的值是经典的算法。

考虑到多项式的处理比较麻烦,不妨对变量a进行多次赋值以判断表达式是否等价。

值得注意,由于进行数值运算,采用哪种数据类型成为程序是否正确的关键。

下面的程序,采取modm的方法,其中m为任意正整数。

当对a多次赋值,且m取不同的较大的正整数时,可以保证算法的正确性。

programequal;

constmax=maxlongint;

constcom:

array[1..7,1..7]ofchar=(('

'

<

),

('

='

X'

));

varthere:

oped:

array[1..1000]oflongint;

optr:

array[1..1000]ofchar;

ned,ntr:

int64;

a,b:

s:

array[0..26]ofstring;

value:

array[0..26,-4..4]ofint64;

array[0..26]ofboolean;

n,i,j,p,q:

functioncompare(w1,w2:

char):

varx1,x2:

integer;

casew1of

+'

:

x1:

-'

=2;

*'

=3;

^'

=4;

('

=5;

)'

=6;

#'

=7;

casew2of

x2:

compare:

=com[x1,x2];

functionoperation(a:

there:

b:

int64):

vari:

casethereof

operation:

=(a+b)modmax;

=(a-b)modmax;

=(a*b)modmax;

beginoperation:

fori:

=1tobdo

=operation*amodmax;

functionexp(s:

aa:

=s+'

;

i:

ned:

ntr:

fillchar(oped,sizeof(oped),0);

optr[1]:

flag:

whilenot((s[i]='

)and(optr[ntr]='

))do

ifs[i]in['

0'

..'

9'

]then

ifnotflagthen

=ned+1;

oped[ned]:

=ord(s[i])-ord('

inc(i);

end

else

=oped[ned]*10+ord(s[i])-ord('

ifs[i]='

a'

then

inc(ned);

=aa;

elseifs[i]='

theninc(i)

casecompare(optr[ntr],s[i])of

beginntr:

=ntr+1;

optr[ntr]:

=s[i];

inc(i);

there:

=optr[ntr];

=ntr-1;

=oped[ned];

ned:

=ned-1;

=operation(a,there,b);

exp:

=oped[1];

equal.in'

readln(f,s[0]);

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

当前位置:首页 > 高中教育 > 初中教育

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

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