真是感动。。喜闻乐见出错数据。。
应该是280分。。
1. 修改文章(amend.pas/c/cpp)
【问题描述】
有一本n个单词的字典,其中每个单词的长度不超过4且大于0。现在给你一篇文章,文章中没有分隔符,只有小写字母。现在需要你修改最少的字母,使文章是由字典中的单词构成。
【输入】第一行一个数n。接下来n行,每行一个单词。(单词可能重复) 接下来一行,一个数m,表示文章中字母的个数。再接下来一行是m个字母,表示文章。
【输出】仅一个数,表示最少需要修改的字母个数,若无法满足要求,则输出“No”(不包括引号)。
嗯。。这题我觉得放错了位置。。
反正我今天是先写了2,3题再写了第1题。。
动态规划。。
设f[i]表示到第i个位置的最小修改字母个数
f[i]=min(f[i],f[i-1]+cost[i,i],f[i-2]+cost[i-1,i],f[i-3]+cost[i-2,i],f[i-4]+cost[i-3,i])
cost[a,b]表示从a到b这一段字符串变成字典里的东西的最少花费。。
cost数组可以先用BFS处理出来。。
由于我用的BFS,计算了很多无用的东西。。
所以每一个点都是0.8s左右。。有点惊险。。
const shuru='amend.in';
shuchu='amend.out';
maxn=400001;
maxm=200001;
long=1000001;
INF=1 shl 28;
type xxxx=array[1..4] of char;
var a:array[0..maxn] of char;
f:array[0..maxn] of longint;
g1:Array['a'..'z'] of longint;
g2:Array['a'..'z','a'..'z'] of longint;
g3:array['a'..'z','a'..'z','a'..'z'] of longint;
g4:Array['a'..'z','a'..'z','a'..'z','a'..'z'] of longint;
queue:Array[0..long] of xxxx;
leng:Array[0..long] of longint;
hash:Array[0..long] of boolean;
data,front,finish,i,j,k,n,m:longint;
mi:array[0..4] of longint;
b,c,d,x:char;
step:xxxx;
function gothash(x:xxxx;leng:longint):longint;
begin
case leng of
1:exit((ord(x[1])-96));
2:exit((ord(x[1])-96)*mi[1]+(ord(x[2])-96));
3:exit((ord(x[1])-96)*mi[2]+(ord(x[2])-96)*mi[1]+(ord(x[3])-96));
4:exit((ord(x[1])-96)*mi[3]+(ord(x[2])-96)*mi[2]+(ord(x[3])-96)*mi[1]+(ord(x[4])-96));
end;
end;
procedure init;
begin
assign(input,shuru);reset(input);
assign(output,shuchu);rewrite(output);
readln(n);
front:=0;
mi[0]:=1;
for i:=1 to 4 do mi[i]:=mi[i-1]*26;
for b:='a' to 'z' do g1[b]:=INF;
for b:='a' to 'z' do for c:='a' to 'z' do g2[b,c]:=INF;
for b:='a' to 'z' do for c:='a' to 'z' do for d:='a' to 'z' do g3[b,c,d]:=INF;
for b:='a' to 'z' do for c:='a' to 'z' do for d:='a' to 'z' do for x:='a' to 'z' do g4[b,c,d,x]:=INF;
for i:=1 to n do
begin
while not(eoln) do
begin
inc(leng[i]);
read(queue[i][leng[i]]);
end;
case leng[i] of
1:g1[queue[i][1]]:=0;
2:g2[queue[i][1],queue[i][2]]:=0;
3:g3[queue[i][1],queue[i][2],queue[i][3]]:=0;
4:g4[queue[i][1],queue[i][2],queue[i][3],queue[i][4]]:=0;
end;
readln;
end;
finish:=n;
readln(m);
for i:=1 to m do read(a[i]);
end;
procedure yuchuli;
begin
fillchar(hash,sizeof(hash),true);
for i:=1 to finish do hash[gothash(queue[i],leng[i])]:=false;
while front<>finish do
begin
inc(front);
for i:=1 to leng[front] do
for x:='a' to 'z' do
begin
step:=queue[front];
step[i]:=x;
data:=gothash(Step,leng[front]);
if hash[data] then begin
case leng[front] of
1:g1[step[1]]:=g1[queue[front][1]]+1;
2:g2[step[1],step[2]]:=g2[queue[front][1],queue[front][2]]+1;
3:g3[step[1],step[2],step[3]]:=g3[queue[front][1],queue[front][2],queue[front][3]]+1;
4:g4[step[1],step[2],step[3],step[4]]:=g4[queue[front][1],queue[front][2],queue[front][3],queue[front][4]]+1;
end;
inc(finish);
queue[finish]:=step;
leng[finish]:=leng[front];
hash[data]:=false;
end;
end;
end;
end;
function min(a,b:longint):longint;
begin
if a<b then exit(A);
exit(B);
end;
procedure search(i:longint);
begin
if i=0 then exit;
if f[i]=f[i-4]+g4[a[i-3],a[i-2],a[i-1],a[i]] then begin
search(i-4);
writeln(i-4);
exit;
end;
if f[i]=f[i-3]+g3[a[i-2],a[i-1],a[i]] then begin
search(i-3);
writeln(i-3);
exit;
end;
if f[i]=f[i-2]+g2[a[i-1],a[i]] then begin
search(i-2);
writeln(i-2);
exit;
end;
if f[i]=f[i-1]+g1[a[i]] then begin
search(i-1);
writeln(i-1);
exit;
end;
end;
procedure main;
begin
init;
yuchuli;
for i:=1 to m do f[i]:=INF;
f[1]:=min(f[1],f[0]+g1[a[1]]);
f[2]:=min(f[2],min(f[0]+g2[a[1],a[2]],f[1]+g1[a[2]]));
f[3]:=min(f[3],min(f[0]+g3[a[1],a[2],a[3]],min(f[1]+g2[a[2],a[3]],f[2]+g1[a[3]])));
for i:=4 to m do f[i]:=min(f[i],min(f[i-4]+g4[a[i-3],a[i-2],a[i-1],a[i]],min(f[i-3]+g3[a[i-2],a[i-1],a[i]],min(f[i-2]+g2[a[i-1],a[i]],f[i-1]+g1[a[i]]))));
if f[m]=INF then writeln('No')
else writeln(f[m]);
search(m);
close(input);close(output);
end;
begin
main;
end.
2. 智力大冲浪(riddle.pas/c/cpp)
【问题描述】
小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则:
首先,比赛时间分为n个时段(n≤500),它又给出了很多小游戏,每个小游戏都必须在规定期限ti前完成(1≤ti≤n)。如果一个游戏没能在规定期限前完成,则要从奖励费m元中扣去一部分钱wi,wi为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱!
傻逼贪心。。
先按价值从大到小排序
然后尽量在后面的时间做。。
const shuru='riddle.in';
shuchu='riddle.out';
maxn=1001;
var a:Array[0..maxn] of longint;
t:Array[0..maxn] of longint;
hash:Array[0..maxn] of boolean;
p,i,j,k,n,m:longint;
procedure init;
begin
assign(input,shuru);reset(input);
assign(output,shuchu);rewrite(output);
readln(m);
readln(n);
for i:=1 to n do read(t[i]);
for i:=1 to n do read(a[i]);
end;
procedure qsort(left,right:longint);
var i,j,mid:longint;
begin
i:=left; j:=right; mid:=a[(i+J) shr 1];
repeat
while a[i]>mid do inc(i);
while a[j]<mid do dec(j);
if i<=j then begin
p:=a[i];a[i]:=a[j];a[j]:=p;
p:=t[i];t[i]:=t[j];t[j]:=p;
inc(i); dec(j);
end;
until i>j;
if j>left then qsort(left,j);
if i<right then qsort(i,right);
end;
procedure main;
begin
init;
qsort(1,n);
fillchar(hash,sizeof(hash),true);
for i:=1 to n do
begin
j:=t[i];
while ((not hash[j]) and (j>0)) do dec(j);
if j=0 then dec(m,a[i]);
hash[j]:=false;
end;
writeln(M);
close(input);close(output);
end;
begin
main;
end.
3. 电梯(lift.pas/c/cpp)
【问题描述】
有一天,快乐的猪做了一个梦,梦见了一座很奇怪的大楼。大楼的每一层楼都可以停电梯,而且第i层楼(1≤i≤N)上有一个数字Ki(0≤Ki≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到1+3=4楼,按“下”是不起作用的,因为没有1-3=-2楼。那么,从A楼到B楼至少要按几次按钮呢?
傻逼宽搜。。最开始有个地方写错了只拿了80分。。
const shuru='lift.in';
shuchu='lift.out';
maxn=201;
long=maxn*100;
var a:array[0..maxn] of longint;
ans,queue:array[0..long] of longint;
hash:array[0..maxn] of boolean;
x,front,finish,aa,b,i,j,k,n:longint;
procedure init;
begin
assign(input,shuru);
assign(output,shuchu);
reset(input);
rewrite(output);
readln(n,aa,b);
if aa=b then begin
writeln(0);
close(input);close(output);
halt;
end;
for i:=1 to n do read(a[i]);
end;
procedure print(n:longint);
begin
writeln(n);
close(input);close(output);
halt;
end;
procedure main;
begin
init;
fillchar(hash,sizeof(hash),true);
queue[1]:=aa; hash[aa]:=false; front:=0; finish:=1;
while front<>finish do
begin
inc(front);
if front>long then front:=front-long;
x:=queue[front];
if (x+a[x]<=n) then if hash[x+A[x]] then begin
inc(finish);
if finish>long then finish:=finish-long;
queue[finish]:=x+a[x];
hash[x+A[x]]:=false;
ans[finish]:=ans[front]+1;
if queue[finish]=b then print(ans[finish]);
end;
if (x-a[x]>=1) then if hash[x-A[x]] then begin
inc(finish);
if finish>long then finish:=finish-long;
queue[finish]:=x-a[x];
hash[x-A[x]]:=false;
ans[finish]:=ans[front]+1;
if queue[finish]=b then print(ans[finish]);
end;
end;
print(-1);
end;
begin
main;
end.