以后编程的时间越来越少罗,上高中要努力罗。这个只能当业余活动,没办法谁叫我没能力上省队啊,有能力的话我都不管文化科了。加油吧,考上个好大学,以后就可以好好研究、编程罗。不过比赛还是要去打打酱油的,看看自己有没进步,少许进步我便满意了。noip复赛貌似在11月把,还有3个月,有时间就练练吧。
----------------------------------------------------------美丽的分界线------------------------------------------------------------------
USACO 1.5.1 Number Triangles 数字金字塔
学DP的入门题
program numtri(input,output);
var
n,i,j:longint;
f:array[1..1000,1..1000] of longint;
procedure init;
begin
assign(input,'numtri.in');
assign(output,'numtri.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
end;
function max(x,y:longint):longint;
begin
if x>y then max:=x
else max:=y;
end;
begin
init;
readln(n);
for i:=1 to n do
begin
for j:=1 to i do read(f[i,j]);
readln;
end;
for i:=n-1 downto 1 do
for j:=1 to i do
f[i,j]:=max(f[i,j]+f[i+1,j],f[i,j]+f[i+1,j+1]);
writeln(f[1,1]);
outit;
end.
USACO 1.5.2 Prime Palindromes 回文质数
这题主要是解决超时问题。做法:先制造回文数,在判断素数。而且回文数除11外,偶数位的回文数都不是素数,都可被11整除。(提示里面有)
USACO里面好多解法,都很简单,我没仔细看。
program pprime(input,output);
var
a,b,i,j,k,med,total,n:longint;
s,s1:string;
g:boolean;
f:array[1..10000] of boolean;
prime:array[1..5000] of longint;
procedure init;
begin
assign(input,'pprime.in');
assign(output,'pprime.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
end;
procedure sushu; //10000内素数表
var
i,j:longint;
begin
f[1]:=false;
i:=2;
while i<=100 do
begin
if f[i] then
begin
j:=i*2;
while j<=10000 do begin f[j]:=false;inc(j,i);end;
end;
inc(i);
end;
total:=0;
for i:=2 to 10000 do
if f[i] then begin inc(total);prime[total]:=i;end;
end;
function ok(k:longint):boolean; //判断是否是素数
var
i:longint;
begin
for i:=1 to total do
if prime[i]>trunc(sqrt(k)) then break
else if k mod prime[i]=0 then exit(false);
exit(true);
end;
begin
init;
fillchar(f,sizeof(f),true);
sushu;
readln(a,b);
i:=1;n:=10;
for med:=1 to 7 do //回文素数的位数,因为8是偶数,9就超过...
begin
if med=2 then
begin
if (a<=11)and(b>=11)then writeln(11);
continue;
end;
if odd(med) then
begin
while i<n do
begin
str(i,s1);
s:=s1;
for j:=length(s1)-1 downto 1 do s:=s+s1[j]; //构成回文
val(s,k);
if a<=k then
begin
if k>b then begin outit;halt;end;
if ok(k) then writeln(k);
end;
inc(i);
end;
n:=n*10; //n是控制i累加,例如1位素数n=10,3位素数n=100,5位素数n=1000
end;
end;
outit;
end.
USACO 1.5.3 Superprime Rib 特殊的质数肋骨
简单的dfs,第一位只能是[2,3,5,7],而后面的位数全都只能是[1,3,7,9],因为是其他的必定是合数。
program sprime(input,output);
var
n:longint;
procedure init;
begin
assign(input,'sprime.in');
assign(output,'sprime.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
end;
function ok(k:longint):boolean;
var
i:longint;
begin
for i:=2 to trunc(sqrt(k)) do
if k mod i=0 then exit(false);
exit(true);
end;
procedure dfs(x,y:longint);
begin
if y=0 then begin writeln(x);exit;end;
if ok(x*10+1) then dfs(x*10+1,y-1);
if ok(x*10+3) then dfs(x*10+3,y-1);
if ok(x*10+7) then dfs(x*10+7,y-1);
if ok(x*10+9) then dfs(x*10+9,y-1);
end;
begin
init;
readln(n);
dfs(2,n-1);
dfs(3,n-1);
dfs(5,n-1);
dfs(7,n-1);
outit;
end.
USACO 1.5.4 Checker Challenge 跳棋的挑战
典型的n皇后问题,但13皇后会超时,所以要优化。优化方法有很多种,USACO题解都有,我用的是对称,减少一半时间。
如果是n为偶数,第一行的皇后在1~n div 2搜索,结果*2就行。但奇数,如果最后个皇后在中间列,则有4种方案,所以要记录最后个皇后是否在中间列,是的话这种方案还要*2。
program checker(input,output);
var
n,i,j,ans,num:longint;
line:array[1..13] of longint;
row,hy1,hy2:array[-30..30] of boolean;
procedure init;
begin
assign(input,'checker.in');
assign(output,'checker.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
end;
procedure print;
var
i:longint;
begin
for i:=1 to n-1 do write(line[i],' ');
writeln(line[n]);
end;
procedure dfs(k:longint);
var
i:longint;
begin
if k=n+1 then
begin
inc(ans);
if ans<=3 then print;
if line[n]=n div 2+1 then inc(num); //判断最后个皇后是否在中间列
end
else
for i:=1 to n do
if row[i] and hy1[k-i] and hy2[k+i] then
begin
line[k]:=i;
row[i]:=false;
hy1[k-i]:=false;
hy2[k+i]:=false;
dfs(k+1);
row[i]:=true;
hy1[k-i]:=true;
hy2[k+i]:=true;
end;
end;
begin
init;
fillchar(row,sizeof(row),true);
fillchar(hy1,sizeof(hy1),true);
fillchar(hy2,sizeof(hy2),true);
readln(n);
if n=6 then dfs(1) //n=6是不能对称
else
begin
for i:=1 to n div 2 do
if row[i] and hy1[1-i] and hy2[1+i] then
begin
line[1]:=i;
row[i]:=false;
hy1[1-i]:=false;
hy2[1+i]:=false;
dfs(2);
row[i]:=true;
hy1[1-i]:=true;
hy2[1+i]:=true;
end;
ans:=ans*2;num:=num*2;
if odd(n) then inc(ans,num);
end;
writeln(ans);
outit;
end.