A 圆盘自动机
循环矩阵什么的,当时真是没看出规律来。应该把中间过程打出来,说不定就找到规律了。

Codeprogram cell;
const FileName='cell';
type matrix=array[1..500] of longint;
var a,t,tmp:matrix;
b,ans:array[1..500] of int64;
n,m,d,k,i,j:longint;
temp:Qword;
procedure OFile;
begin
assign(input,FileName+'.in');
assign(output,FileName+'.out');
reset(input);rewrite(output);
end;
procedure CFile;
begin
close(input);close(output);end;
procedure mul(var a,b,ans:matrix);
var i,j:longint;
temp:Qword;
begin
for i:=1 to n do
begin
temp:=0;
for j:=1 to n do
temp:=(temp+int64(A[j])*B[(n+i-j)mod n+1])mod m;
ans[i]:=temp;
end;
end;
procedure print(var a:matrix);
var i,j:longint;
begin
for i:=1 to n do begin
for j:=1 to n do
write(a[(n+j-i)mod n+1]:3);
writeln;end;
end;
begin
OFile;readln(n,m,d,k);
fillchar(A,sizeof(a),0);
fillchar(t,sizeof(t),0);
for i:=1 to n do
begin read(B[i]);B[i]:=B[i] mod m;end;
//===init===
T[1]:=1;
for i:=1 to d+1 do A[i]:=1;
for i:=n downto n-d+1 do A[i]:=1;
//===Power===
while k>0 do begin
if(k and 1)>0
then begin
tmp:=T;
mul(tmp,A,T);
end;
tmp:=A;mul(tmp,tmp,A);
k:=k>>1;end;
//===slove===
for i:=1 to n do begin
temp:=0;
for j:=1 to n do
temp:=((Qword(T[(n+j-i)mod n+1])*B[j])mod m
+temp)mod m;
ans[i]:=temp;
end;
//===print===
for i:=1 to n-1 do
write(ans[i],' ');
writeln(ans[n]);CFile;
end.
B 游戏
先把2D/2D的方程列出来,然后是一个结论((a+b)(c+d)>ac+bd)优化到2D/0D。讲题之前完全想不到啊。第一次接触。这个题目唯一一个难点就在这里。

Codeprogram game;
uses math;
const FileName='game';
maxl=2000;
var f:array[0..maxl,0..maxl] of longint;
a,b:array[1..maxl] of longint;
i,j,l1,l2:longint;
begin
filldword(F,sizeof(f)>>2,maxlongint);
F[0][0]:=0;readln(L1,L2);
for i:=1 to L1 do begin read(A[i]);dec(A[i]);end;
for i:=1 to L2 do begin read(B[i]);dec(B[i]);end;
for i:=1 to L1 do
for j:=1 to L2 do
F[i][j]:=min((F[i-1][j-1]),min(F[i-1][j],F[i][j-1]))
+A[i]*B[j];
writeln(F[L1][L2]);
end.
C 方块(square)
这个题目还是比较有意思,虽然很裸,但是我猜测这种题目是现在NOIp出题的比较可能的方向。之前没怎么写过这种题目,关键还是规律,思路要清晰。整个程序可以说只有这两行:
pos[i]:=max{pos[j]+min(len[i],len[j])}(j=1..i-1)
pos[i]:=pos[i]*sqrt2;
这两行就是题目考察我们的思维能力的地方。还有就是判断是否被遮挡要注意细节,把它投影到X轴上看,还有就是某一块既可以被左边挡住,也坑能呗右边挡住;一个方块既可能被另一个方块挡住,也可能被两个方块挡住。

Codeprogram square;
uses math;
const Filename='square';maxn=50;
var sqrt2,tmp:extended;
len:array[1..maxn] of longint;
l,r,pos:array[1..maxn] of extended;
i,j,n:longint;
function cansee(k:integer):boolean;
var i:integer;
begin
cansee:=true;
for i:=1 to n do begin
if(i<k)and(len[i]>len[k])
then l[k]:=min(max(r[i],l[k]),r[k]);
if(i>k)and(len[i]>len[k])
then r[k]:=max(min(l[i],r[k]),l[k]);
if abs(l[k]-r[k])<1E-9 then exit(false);
end;
end;
begin
Sqrt2:=sqrt(2);
while not eof do begin
readln(n);for i:=1 to n do read(len[i]);
pos[1]:=len[i]/2;
for i:=2 to n do begin
for j:=1 to i-1 do
tmp:=max(pos[j]+min(len[i],len[j]),tmp);
pos[i]:=tmp;tmp:=0;end;
for i:=1 to n do begin
pos[i]:=pos[i]*sqrt2;
l[i]:=pos[i]-len[i]/sqrt2;
r[i]:=pos[i]+len[i]/sqrt2;
end;
for i:=1 to n do
if cansee(i)
then write(i,' ');
writeln;end;
end.