染色的立方体_NOI导刊2010提高(03)

考场没切掉.

本题其实就是一个暴搜+结论的题目,具体题解在下方。


考场时的想法:

1.贪心

看能不能找到最佳的合适位置,很显然:效率低,正确率也低。

2.结论

想起不管上下左右怎样转,只有24种转法,增加了这个条件,就可以爆搜了。

考场即时验证:

procedure make(mode,x,y:longint);// 草稿枚举上下左右翻转
begin
        if mode=1 then
        begin
                may_color[x,1]:=may_color[y,1];
                may_color[x,2]:=may_color[y,3];
                may_color[x,3]:=may_color[y,5];
                may_color[x,4]:=may_color[y,2];
                may_color[x,5]:=may_color[y,4];
                may_color[x,6]:=may_color[y,6];
        end;
        if mode=2 then
        begin
                may_color[x,1]:=may_color[y,1];
                may_color[x,2]:=may_color[y,4];
                may_color[x,3]:=may_color[y,2];
                may_color[x,4]:=may_color[y,5];
                may_color[x,5]:=may_color[y,3];
                may_color[x,6]:=may_color[y,6];
        end;
        if mode=3 then
        begin
                may_color[x,1]:=may_color[y,4];
                may_color[x,2]:=may_color[y,2];
                may_color[x,3]:=may_color[y,1];
                may_color[x,4]:=may_color[y,6];
                may_color[x,5]:=may_color[y,5];
                may_color[x,6]:=may_color[y,3];
        end;
        if mode=4 then
        begin
                may_color[x,1]:=may_color[y,3];
                may_color[x,2]:=may_color[y,2];
                may_color[x,3]:=may_color[y,6];
                may_color[x,4]:=may_color[y,1];
                may_color[x,5]:=may_color[y,5];
                may_color[x,6]:=may_color[y,4];
        end;
end;

procedure items;
var
        i,j,a,b,c,d,e,f,head,tail:longint;
begin
        for i:=1 to 6 do
                may_color[1,i]:=i;
        head:=0;
        tail:=1;
        repeat  //翻转状态
                inc(head);
                for j:=1 to 4 do
                begin
                        inc(tail);
                        make(j,tail,head);
                end;
        until tail>=96;
        for i:=1 to 96 do
                ask[may_color[i,1],may_color[i,2],may_color[i,3],may_color[i,4],may_color[i,5],may_color[i,6]]:=True;
        for a:=1 to 6 do for b:=1 to 6 do for c:=1 to 6 do for d:=1 to 6 do for e:=1 to 6 do for f:=1 to 6 do
        if ask[a,b,c,d,e,f] then //判断可能
        begin
                inc(x);
                able[x,1]:=a;
                able[x,2]:=b;
                able[x,3]:=c;
                able[x,4]:=d;
                able[x,5]:=e;
                able[x,6]:=f;
        end;
end;

这里的able也就是可能翻转的状态了。
得出已下状态:

注释:add(x,状态);表示第x个状态翻转。
		add(1,1,2,3,4,5,6);
        add(2,1,3,5,2,4,6);
        add(3,1,4,2,5,3,6);
        add(4,1,5,4,3,2,6);
        add(5,2,1,4,3,6,5);
        add(6,2,3,1,6,4,5);
        add(7,2,4,6,1,3,5);
        add(8,2,6,3,4,1,5);
        add(9,3,1,2,5,6,4);
        add(10,3,2,6,1,5,4);
        add(11,3,5,1,6,2,4);
        add(12,3,6,5,2,1,4);
        add(13,4,1,5,2,6,3);
        add(14,4,2,1,6,5,3);
        add(15,4,5,6,1,2,3);
        add(16,4,6,2,5,1,3);
        add(17,5,1,3,4,6,2);
        add(18,5,3,6,1,4,2);
        add(19,5,4,1,6,3,2);
        add(20,5,6,4,3,1,2);
        add(21,6,2,4,3,5,1);
        add(22,6,3,2,5,4,1);
        add(23,6,4,5,2,3,1);
        add(24,6,5,3,4,2,1);

暴搜是地球人都会的:

procedure check;
var
        i,j,k,sum,km,ss:longint;
begin
        ss:=0;
        for k:=1 to 6 do
        begin
                km:=6666;
                for i:=1 to n do
                begin
                        sum:=0;
                        for j:=1 to n do
                                if j<>i then
                                        if use[i,k]<>use[j,k] then
                                                inc(sum);
                        if sum<km then
                                km:=sum;
                end;
                inc(ss,km);
        end;
        if ss<ans then
                ans:=ss;
end;

procedure work_(x:longint);
var
        i,j:longint;
begin
        sum:=0;
        if x=n+1 then
                check
        else
                for i:=1 to 24 do
                begin
                        for j:=1 to 6 do
                                use[x,j]:=color[x,able[i,j]];
                        work_(x+1);
                end;
end;

begin
        items;
        repeat
                ans:=6666;
                sum:=0;
                read_;
                work_(1);
                writeln(ans);
        until 1<0;
end.

psacal会卡,90分,所以各位看完请写c++吧

posted @ 2018-09-23 15:16  _ARFA  阅读(185)  评论(0编辑  收藏  举报