Usaco1.2 我的程序和题解
http://hi.baidu.com/mfs666/blog/item/8d2d95ef0a020deacf1b3e62.html
1.2.1.Milking Cows (milk2):
这个题看起来可以直接按照时间轴模拟,但是显然100万大了点,虽然实际上数据没有这么BT,但是还是没敢这么做。于是自己想了一种算法,貌似是对的。
思路就是用一排数组元素来对应区间,那么整个数组就是数轴,每次加入新区间的时候都保持里面的区间都是不重合而且有序的,这样加入了所有的区间后就是完整的数轴,找出要求的区间就好办了。问题就是如何保持数组的性质,如果开始的时候不保证有序,那么加入时可能就要都扫一遍,比较麻烦,于是先按照每个区间的起始位置升序排序(使用快排),无视结束位置,但是不要忘了移动时都要移动。然后从第一个开始加入,这样每一个新加入的区间一定比前面的区间的开始位置晚,这样就可以保证内部有序,所以只用跟最后一个比较即可,分为三种情况:1)新的区间结束位置比最晚区间的结束位置早,直接无视 2)新的区间开始位置比最晚区间的结束位置晚,加入作为新的最晚区间 3)新的区间结束位置比最晚区间的结束位置晚,将最晚区间的结束位置更新为新区间,这样就可以了
这个方法貌似就是Nocow里的那个离散化做法,不过确实是我自己想的,不知道以后会不会还有关于区间的题用得上
第一次似乎没有考虑只有一个区间的情况,第一个点没过,改了一下,结果改错了,后面的点有过不了,又改了一次,三次AC,都是实现上的问题,编码能力阿
至于传说中的线段树,不会。。。
code:
{
ID: mfs.dev2
PROG: milk2
LANG: PASCAL
}
program milk2;
type p=record
b,e:longint;
end;
var
n,y,w,i,f,t:longint;
x,h:array[0..5000] of p;
procedure quicksort(s,t:longint);
var
i,j,q:longint;
t1:p;
begin
i:=s; j:=t; q:=x[(i+j) div 2].b;
repeat
while (x[i].b<q) do inc(i);
while (x[j].b>q) do dec(j);
if (i<=j) then begin
t1:=x[i]; x[i]:=x[j]; x[j]:=t1;
inc(i); dec(j);
end;
until i>j;
if (s<j) then quicksort(s,j);
if (i<t) then quicksort(i,t);
end;
begin
assign(input,'milk2.in');
assign(output,'milk2.out');
reset(input);rewrite(output);
readln(n);
for i:=1 to n do
readln(x[i].b,x[i].e);
quicksort(1,n);
inc(f);
h[f]:=x[1];
for i:=2 to n do begin
if x[i].b>h[f].e then begin
inc(f);
h[f]:=x[i];
continue;
end;
if x[i].e<h[f].e then
continue;
h[f].e:=x[i].e;
end;
for i:=1 to f do begin
t:=h[i].e-h[i].b;
if t>y then
y:=t;
end;
for i:=1 to f-1 do begin
t:=h[i+1].b-h[i].e;
if t>w then
w:=t;
end;
writeln(y,' ',w);
close(output);
end.
1.2.2.Transformations (transform):
这个题纯粹猥索,考研耐心的。旋转180度就是转两次90度,270度就是3次,所以写两个变换过程,转90度和翻转,用二维数组存方块,另写一个检查是否相同的过程,这样一个一个试就行了,一次AC。
code:
{
ID: mfs.dev2
PROG: transform
LANG: PASCAL
}
program transform;
type k=array[1..10,1..10] of char;
var
b,a,t:array[1..10,1..10] of char;
i,j,f,n,r:integer;
procedure c1(c:k);
var i,j:integer;
ttt:array[1..10,1..10] of char;
begin
ttt:=c;
for i:=1 to n do
for j:=1 to n do
t[i,j]:=ttt[j,n+1-i];
end;
procedure c4(c:k);
var i,j:integer;
ttt:array[1..10,1..10] of char;
begin
ttt:=c;
for i:=1 to n do
for j:=1 to n do
t[i,j]:=ttt[n+1-i,j];
end;
procedure cc;
var i,j,tt:integer;
begin
tt:=0;f:=0;
for i:=1 to n do
for j:=1 to n do
if t[i,j]<>a[i,j] then begin
tt:=1;break;
end;
if tt=0 then
f:=1;
end;
begin
assign(input,'transform.in');
assign(output,'transform.out');
reset(input);
rewrite(output);
readln(n);
for j:=1 to n do begin
for i:=1 to n do
read(b[i,j]);
readln;
end;
for j:=1 to n do begin
for i:=1 to n do
read(a[i,j]);
readln;
end;
c1(b);cc;
if (f=1) and (r=0) then
r:=1;
c1(b);c1(t);cc;
if (f=1) and (r=0) then
r:=2;
c1(b);c1(t);c1(t);cc;
if (f=1) and (r=0) then
r:=3;
c4(b);cc;
if (f=1) and (r=0) then
r:=4;
c1(t);cc;
if (f=1) and (r=0) then
r:=5;
c4(b);
c1(t);c1(t);cc;
if (f=1) and (r=0) then
r:=5;
c4(b);
c1(t);c1(t);c1(t);cc;
if (f=1) and (r=0) then
r:=5;
t:=b;cc;
if (f=1) and (r=0) then
r:=6;
if r=0 then r:=7;
writeln(r);
close(output);
end.
1.2.3.Name That Number (namenum)
这个是读入字典,判断符不符合给出的长度,符合的话转换成数字,看看是否符合给的数字。转换为数字的方法是利用ASCII码自动打表,因为q和z不在表中,所以要手动设成0,所与a到p,一个打表的循环,r到y一个。这个题告诉我们的就是要有些逆向思维。打表时算错了个地方,所以二次AC。
至于传说中的动态单词查找树,我今天好像看明白了,就是读入后用链表建树,把有单词的位置设成1,然后查的时候,若遇到nil,说明不在字典中,或者到了位置是0,也是不在字典中。但是那个并不比这个快,就先不写了。
code
{
ID: mfs.dev2
PROG: namenum
LANG: PASCAL
}
program namenum;
var
n,p,g,e:string;
i,a,l0,j,c:integer;
t:array[65..90] of integer;
begin
assign(input,'namenum.in');
assign(output,'namenum.out');
reset(input);
rewrite(output);
readln(n);
close(input);
assign(input,'dict.txt');
reset(input);
l0:=length(n);
for i:=65 to 80 do begin
a:=i-65;
a:=(a div 3)+2;
t[i]:=a;
end;
t[81]:=0;
t[90]:=0;
for i:=82 to 89 do begin
a:=i-81;
a:=(a div 3)+7;
t[i]:=a;
end;
while not eof do begin
readln(p);
g:='';
if length(p)=l0 then begin
for i:=1 to l0 do begin
a:=ord(p[i]);
Str(t[a],e);
g:=g+e;
end;
if g=n then begin
inc(c);
writeln(p);
end;
end;
end;
if c=0 then
writeln('NONE');
close(output);
end.
1.2.4 Palindromic Squares (palsquare)
正如nocow题解所说,唯一的知识点就是进制转换,用了一个比较简单好写的递归型式转换,很好用,以后可以用,一次AC
code
{
ID: mfs.dev2
PROG: palsquare
LANG: PASCAL
}
program palsquare;
Const
w='0123456789ABCDEFGHIJ';
var
s,sq:string;
i,k,fl,si:longint;
procedure cha(nu:longint;var s:string);
var
m,n:longint;
begin
m:=nu div k;
n:=nu mod k;
s:=w[n+1]+s;
If m<>0 then cha(m,s)
end;
procedure che(a:string);
var
i,l,t:longint;
begin
fl:=1;
l:=length(a);
t:=l+1;
for i:=l downto 1 do
if a[i]<>a[t-i] then begin
fl:=0;
break;
end;
end;
begin
assign(input,'palsquare.in');
assign(output,'palsquare.out');
reset(input);rewrite(output);
readln(k);
for i:=1 to 300 do begin
si:=sqr(i);
s:='';
cha(si,s);
che(s);
if fl=1 then begin
sq:=s;
s:='';
cha(i,s);
writeln(s,' ',sq);
end;
end;
close(output);
end.
1.2.5 Dual Palindromes (dualpal)
同上,一个一个进制统计,够了两个就跳出,够了个数就跳出
code
{
ID: mfs.dev2
PROG: dualpal
LANG: PASCAL
}
program dualpal;
Const
w='0123456789ABCDEFGHIJ';
var
nn,b,c,fc,fl,i,j,dq:longint;
s:string;
procedure cha(nu,k:longint;var s:string);
var
m,n:longint;
begin
m:=nu div k;
n:=nu mod k;
s:=w[n+1]+s;
If m<>0 then cha(m,k,s)
end;
procedure che(a:string);
var
i,l,t:longint;
begin
fl:=1;
l:=length(a);
t:=l+1;
for i:=l downto 1 do
if a[i]<>a[t-i] then begin
fl:=0;
break;
end;
end;
begin
assign(input,'dualpal.in');
assign(output,'dualpal.out');
reset(input);rewrite(output);
readln(nn,b);
dq:=b+1;
while c<nn do begin
fc:=0;
str(dq,s);
che(s);
if fl=1 then
inc(fc);
i:=9;
while (fc<2) and (i>=2) do begin
s:='';
cha(dq,i,s);
che(s);
if fl=1 then
inc(fc);
dec(i);
end;
if fc>=2 then begin
writeln(dq);
inc(c);
end;
inc(dq);
end;
close(output);
end.

浙公网安备 33010602011771号