mok
題目描述
N個杯子,第i個容量爲Vi,一開始所有杯子裝滿水,每次可以
1) 將一個杯子中的水倒掉。
2) 將杯子A中的水全部倒入杯子B(如果不會溢出的話)。
3) 用杯子A中部分的水填滿杯子B(如果夠的話)。
問能否通過若干次倒水得到目標狀態。
輸入文件
第一行N 表示杯子個數
第二行N個數 表示每個杯子的容量
第三行N個數 表示目標狀態中每個杯子的水量
輸出文件
若可以,輸出最少步數,否則輸出NIE
樣例輸入
3
3 5 5
0 0 4
樣例輸出
6
數據約定
100%:N<=4,1<=Vi<=50
覺得過於不屑以及LZSB的請 滾出 + <Ctrl + W>
排除了許多不和諧因素之後進入正題
記得當初是三個桶子
記得當初廣搜寫得醜得和一坨翔一樣
獻上mt的神code 真心覺得寫得好!!!
用C++重寫一遍的話就感覺不那麼神了, 於是還是貼mt的原代碼!!!
program mt;
const
inf = 'mok.in';
ouf = 'mok.out';
var
l, r: array[1 .. 4] of longint;
q: array[1 .. 150000, 1 .. 4] of longint;
f: array[0 .. 49, 0 .. 49, 0 .. 49, 0 .. 49] of longint;
i, j, k, ff, rr, n: longint;
procedure ins;
begin
if f[r[1], r[2], r[3], r[4]] < 0 then begin
f[r[1], r[2], r[3], r[4]] := k + 1;
inc(rr); q[rr] := r
end;
end;
BEGIN
assign(input, inf); reset(input);
assign(output, ouf); rewrite(output);
read(n);
for i := 1 to n do read(l[i]);
fillchar(f, sizeof(f), $FF);
k := -1; r := l; ins;
while ff < rr do begin
inc(ff);
r := q[ff];
k := f[r[1], r[2], r[3], r[4]];
for i := 1 to n do
for j := 1 to n do
if (i <> j) and (q[ff, j] <> l[j]) then begin
r := q[ff];
if r[i] + r[j] <= l[j] then begin
r[j] := r[j] + r[i]; r[i] := 0;
end
else begin
r[i] := r[i] - l[j] + r[j]; r[j] := l[j];
end;
ins
end;
for i := 1 to n do
if q[ff, i] > 0 then begin
r := q[ff]; r[i] := 0;
ins;
end;
end;
for i := 1 to n do read(r[i]);
if f[r[1], r[2], r[3], r[4]] >= 0 then writeln(f[r[1], r[2], r[3], r[4]])
else writeln('NIE');
close(input); close(output);
END.