四:zj之转化模式 众所舟舟知……zj同学会转换模式,我们对两种模式的定义为;♀♂,其实zj的模式转换是建立在他身体的细胞模式转换之上的,比如说这里有6*6的细胞: ♀♂♀♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
所以大家就知道为什么zj的模式总是介于两者之间了,因为他的每个细胞的模式不一样! Zj的细胞和zj一样有很多的坏毛病,当一个细胞转换模式时,他也会使它上,下,左,右四个细胞转换模式,但是仍算转换一步。比如,对于上图(1,2)的转换模式后总的模式变为:
♂♀♂♂♀♂
♀♀♀♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
(3,3)转换模式后总的模式变为:
♀♂♀♂♀♂
♀♂♂♂♀♂
♀♀♂♀♀♂
♀♂♂♂♀♂
♀♂♀♂♀♂
♀♂♀♂♀♂
好了,现在问题来了,zj现在想把n*n的细胞全部转换成♂模式,若不能转化输出‘NO’,若能输出最少需要几步。
注意:为了描述生动应用了♀♂符号,但word中的符号与pascal中的不一样,读入以pascal中的为准,pascal中为了转换方便最好使用ASCII码,♂11,♀12.
样例输入:(数据请粘贴change.in)(粘到pascal中就能看到了)
3
♂♀♂
♀♀♀
♂♀♂
样例输出:
1
范围: 50% n<=5; 100% n<=10;
枚举+模拟 (规定 ♂ 为 1,♀ 为 0) 首先, dfs 第一行, dfs 它是变还是不变。然后从第二行开始模拟,如果第一行对应的变了,那么他一定变,以此类推。如果第一行不是 1 ,那么为了让第一行全变成 1 ,则,它一定要变,然后在模拟第三行。。。。。。 最后判断最后一行是否全是 1 ,如果全是 1 ,则成功,反之,输出 NO 或继续 DFS 第一行。
代码(XMC)
var i,j,k,n,m,p,ii,jj:Longint;
a,b:array[1..11,1..11] of integer;
ch:char; sum,ans:longint;
flag:boolean;
procedure init;
begin
readln(n);
for i:=1 to n do
begin
for j:=1 to n do
begin
read(ch);
if ord(ch)=11 then a[i,j]:=1 else a[i,j]:=0;
end;
readln;
end;
end;
procedure main;
begin
ans:=maxlongint;
for i:=0 to (1<<n-1) do
begin
sum:=0;
b:=a;
for j:=1 to n do
if (i and (1<<(n-j)))<>0 then
begin
inc(sum);
b[1,j]:=1-b[1,j];
b[2,j]:=1-b[2,j];
if (j<>1) then b[1,j-1]:=1-b[1,j-1];
if (j<>n) then b[1,j+1]:=1-b[1,j+1];
end;
for ii:=2 to n do
for jj:=1 to n do
begin
if b[ii-1,jj]=0 then
begin
inc(sum);
b[ii,jj]:=1-b[ii,jj];
if (ii<>n) then b[ii+1,jj]:=1-b[ii+1,jj];
if (jj<>1) then b[ii,jj-1]:=1-b[ii,jj-1];
if (jj<>n) then b[ii,jj+1]:=1-b[ii,jj+1];
end;
end;
flag:=true;
for ii:=1 to n do
if b[n,ii]=0 then flag:=false;
if flag and (sum<ans) then ans:=sum;
end;
if ans=maxlongint then writeln('NO') else writeln(ans);
end;
begin
assign(input,'change.in');reset(input);
assign(output,'change.out');rewrite(output);
init;
main;
close(input); close(output);
end.