感觉看完题解能懂1,、2题,后悔比赛的时候没有多想一想。把这个比赛当成vain杯了,就第二题交了个样例,烦死了。
七夕祭
环形纸牌均分,O(n^2)暴力可得70,如果找中位数是O(n logn)就A掉了。需要注意的是,如果n为偶数中位数取中间那两个都可以。
Code
type data=array[0..1000000] of longint;
Pointer=^data;
var i,x,y,m,n,t:longint;
a,b:data;
procedure swap(var a,b:longint);
var t:longint;begin t:=a;a:=b;b:=t;end;
procedure Qsort(p:Pointer;l,r:longint);
var i,j,mid:longint;
begin
i:=l;j:=r;mid:=p^[(l+r)>>1];
repeat
while(i<r)and(p^[i]<mid)do inc(i);
while(l<j)and(mid<p^[j])do dec(j);
if i<=j then begin
swap(p^[i],p^[j]);
inc(i);dec(j);
end;
until i>=j;
if(i<r)then Qsort(p,i,r);
if(l<j)then Qsort(p,l,j);
end;
function calc(a:data;n:longint):int64;
var i:longint;
s:data;
begin
calc:=0;
for i:=1 to n do
s[i]:=s[i-1]+a[i]-a[0] div n;
Qsort(@s,1,n);
for i:=1 to n do
inc(calc,abs(s[i]-s[(n+1)>>1]));
end;
BEGIN
readln(n,m,t);
for i:=1 to t do
begin
readln(x,y);
inc(a[x]);inc(a[0]);
inc(b[y]);inc(b[0]);
end;
if (a[0] mod n=0)and
(b[0] mod m=0)then
writeln('both ',calc(a,n)+calc(b,m))
else begin
if(a[0] mod n=0)then writeln('row ',calc(a,n));
if(b[0] mod m=0)then writeln('column ',calc(b,m));
if (a[0] mod n<>0)and
(b[0] mod m<>0)then writeln('impossible');
end;
END.
太鼓达人
题目的关键在于抽象出图论模型,然后将求哈密顿路(NPC啊亲~)转化为欧拉回路问题并证明欧拉回路的存在。
第一反应,建一个图,点与0到2^k-1的二进制数对应,每个点u向与(u<<1)and((1<<k)-1)和(u<<1+1)and((1<<k)-1)的点连边,图中一共有2*2*2^(k-1)条边,求哈密顿路,如果不存在答案就是最长的一条只经过任意点一次的路径长度。然后我重新构图,把原图中的点变成边,边变成点。在新图中有2^(k-1)个点2^k条边,容易证明这个图存在欧拉回路,所以原图存在哈密顿路,直接DFS就行了。
这个程序是在求哈密顿路!!!但是认为u是边的话,应该是在新图里求欧拉路吧。我现在很糊涂!!郁闷!!
这个题目还是蛮有意思的,认为u是边的话刚好u>>1是起点 ,u and(1<<(k-1))是终点。所以怎么解释都行吧。
Code
CONST FileName='taiko';
maxn=1<<11;
var vis:array[0..maxn] of boolean;
path:array[1..maxn] of longint;
count,i,j,k:longint;
procedure DFS(u:longint);
begin
u:=u and((1<<k)-1);
if vis[u] then exit;
vis[u]:=true;
DFS(u<<1);DFS(u<<1 or 1);
inc(count);path[count]:=u;
end;
BEGIN
readln(k);writeln(1<<k);DFS(0);
for i:=k-1 downto 1 do write((path[count]>>i)and 1);
for i:=count downto k do write(path[i]and 1);
writeln;
END.