July 14th 模拟赛C T3 灌水 Solution
2016-07-14 21:31
423 查看
空降题目处
点我点我点我
•如果前一天被灌了奇数次的水,他们将会给每个朋友灌一次水;
•如果前一天被灌了偶数次的水,他们将会给每个朋友灌两次水。
学生编号为1到N,Alice为1号,学生之间的朋友关系会给出。
计算H天后一共灌了几次水。
4 1
0110
1001
1001
0110
输入2:
4 2
0110
1001
1001
0110
输入3:
5 3
01000
10110
01000
01001
00010
2
输出2:
14
输出3:
26
至于为什么。。。“自行脑补”——AK晗。
点我点我点我
Description:
学生都很喜欢灌水,第一天只有Alice给她的每个朋友灌了一次水,从第二天开始,所有学生(包括Alice)将会有规律地去灌水:•如果前一天被灌了奇数次的水,他们将会给每个朋友灌一次水;
•如果前一天被灌了偶数次的水,他们将会给每个朋友灌两次水。
学生编号为1到N,Alice为1号,学生之间的朋友关系会给出。
计算H天后一共灌了几次水。
Input
输入1:4 1
0110
1001
1001
0110
输入2:
4 2
0110
1001
1001
0110
输入3:
5 3
01000
10110
01000
01001
00010
Output
输出1:2
输出2:
14
输出3:
26
Solution
更新状压状态T直至出现循环。至于为什么。。。“自行脑补”——AK晗。
Program
var c:char; y,e,ans:int64; i,j,k,n,h,t:longint; f,w:array [0..1050000] of longint; d:array [1..20,0..20] of longint; m:array [1..20] of longint; begin readln(n,h); for i:=1 to n do begin for j:=1 to n do begin read(c); if c='1' then begin inc(d[i][0]); d[i][d[i][0]]:=j; end; end; readln; end; m[1]:=1; for i:=2 to n do m[i]:=m[i-1]*2; for i:=1 to d[1][0] do t:=t+m[d[1][i]]; e:=d[1][0]; f[t]:=1; w[t]:=e; for k:=2 to h do begin y:=t; t:=0; for i:=1 to n do if y and m[i]<>0 then begin for j:=1 to d[i][0] do if t and m[d[i][j]]<>0 then t:=t-m[d[i][j]] else t:=t+m[d[i][j]]; e:=e+d[i][0]; end else begin e:=e+d[i][0]*2; end; if f[t]=0 then begin f[t]:=k; w[t]:=e; end else begin ans:=w[t]+(h-f[t]) div (k-f[t])*(e-w[t]); h:=h-f[t]; h:=h mod (k-f[t]); break; end; end; if ans<>0 then begin e:=0; for k:=1 to h do begin y:=t; t:=0; for i:=1 to n do if y and m[i]<>0 then begin for j:=1 to d[i][0] do if t and m[d[i][j]]<>0 then t:=t-m[d[i][j]] else t:=t+m[d[i][j]]; e:=e+d[i][0]; end else begin e:=e+d[i][0]*2; end; end; end; writeln(ans+e); end.