NOIP2013参赛总结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
NOIP2013参赛总结
安阳市七中
常可
一、题解
1、count
这道题其实并不难,不过是简单的模拟。那些做不出来的真不知道是怎么学的。
程序:
program count;
var
s:string;
c:char;
i,j,n,k,sum:longint;
begin
assign(input,'count.in');
reset(input);
assign(output,'count.out');
rewrite(output);
readln(n,j);
c:=chr(j+48);
for i:=1to n do
begin
str(i,s);
for k:=1to length(s)do if s[k]=c then inc(sum);
end;
writeln(sum);
close(input);
close(output);
end.
我的程序采用了字符串,这样可以使程序稍短一些,不过不用的话也没有问题,大家可以自己想想。
2、expr
这道题不算简单,和前几年的相比还是有些难度的,标准算法是栈,当然也有很多其他的方法。一种比较好理解的是:
从头开始搜索字符串,发现“+”的话把之前(我们这里的意思是从上一个加号到这一个加号,都不含加号)的字符串进行乘法运算。由于这个字串里都是乘法运算,只需类似于第一步处理加号时的运算,在搜到乘号时乘上两乘号之间的数即可。
为了防止奇葩的数据,我们要在字符串后加上一个“+”,在每个加号前都加上一个“*”。举个例子吧:
1*2*3*4
这个字串里没有加号,程序会因搜不到加号而得不出结果。因此,要先在末尾加一个“+”,变成这样:
1*2*3*4+
这样程序搜到加号后,就会正常的运算。乘号的道理是一样的。
接下来我们模拟一下程序的执行过程(以样例为标准):
1+1234567890*1
1、添加号,变成1+1234567890*1+
2、添乘号,变成1*+1234567890*1*+
3、搜到第一个加号,加号前的字串是1*,乘法运算得到1,累加变量+1
4、搜到第二个加号,加号前的字串是1234567890*1*,乘法运算得到7890,累加变量+7890
5、结束,输出累加变量7891。
当然,添加乘号的工作也可以在大循环中进行,可以让代码短一点。
程序:
program expr;
var
s,q,m,a:ansistring;
i,j,k,l,sum,ls,ls2:longint;
begin
assign(input,'expr.in');
reset(input);
assign(output,'expr.out');
rewrite(output);
readln(s);
s:=s+'+';
j:=1;
for i:=1to length(s)do
begin
if s[i]='+'then begin
k:=1;
l:=k;
ls2:=1;
a:=a+'*';
repeat
while(a[k]<>'*')do inc(k);
m:=copy(a,l,k-l);
val(m,ls);
ls:=ls mod10000;
ls2:=(ls2*ls)mod10000;
inc(k);
l:=k;
until k>length(a);
sum:=(sum+ls2)mod10000;
a:='';
end
else a:=a+s[i];
end;
writeln(sum);
close(input);
close(output);
end.
3、number
这题其实不难,考验的就是读题的认真程度。我就因为少看了两个字丢了90分啊……
首先是特征值的计算。这个特征值是连续若干个(最少有一个)小朋友手上的数字之和的最大值,既然是连续的,我们可以用模拟的方法,把第几个到第几个的数值都算一遍,然后比较,就像这样(样例):
12345 11
232
3653
410974
515141295
横着的为起点,竖着的为终点,那表中的就是从横的哪个数开始,一直到竖着的那个数之和。
所以每个数的特征值就是起点和终点都不大于它的所有数中的最大值。所以1的特征值为1,2的为3,3的为6,4的为10,5的为15。
这个数据太特殊了,我们换一个有正有负的(就是第一组数据):-409-40197-96-301
-409-409
-401-810-401
97-713-30497
-96-809-4001-96
-301-1110-701-300-397-301所以-409的特征值为-409,-401的特征值为-401,97的特征值为97,-96的特征值为97,-301的特征值为97。
这种算法比较容易实现,但有两个问题,一是空间要用二维数组,在1000000的数据下一定会爆;二是每次找最大值是n^2的时间复杂度,可能超时,于是我们一定要优化。
首先,我们从后往前,找到以最后一个数为终点,最大的连续区间,把这个数的特征值暂定为这个连续区间的和。然后把连续区间的起点一直到终点前的一个数的特征值暂时改为它后面一个数的特征