zoukankan      html  css  js  c++  java
  • 二进制<4>

    位运算简介及实用技巧(四):实战篇

        下面分享的是我自己写的三个代码,里面有些题目也是我自己出的。这些代码都是在我的Pascal时代写的,恕不提供C语言了。代码写得并不好,我只是想告诉大家位运算在实战中的应用,包括了搜索和状态压缩DP方面的题目。其实大家可以在网上找到更多用位运算优化的题目,这里整理出一些自己写的代码,只是为了原创系列文章的完整性。这一系列文章到这里就结束了,希望大家能有所收获。
        Matrix67原创,转贴请注明出处。


    Problem : 费解的开关

    题目来源
        06年NOIp模拟赛(一) by Matrix67 第四题

    问题描述
        你玩过“拉灯”游戏吗?25盏灯排成一个5×5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。
        我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态

    10111
    01101
    10111
    10000
    11011

        在改变了最左上角的灯的状态后将变成:

    01111
    11101
    10111
    10000
    11011

        再改变它正中间的灯后状态将变成:

    01111
    11001
    11001
    10100
    11011

        给定一些游戏的初始状态,编写程序判断游戏者是否可能在6步以内使所有的灯都变亮。

    输入格式
        第一行有一个正整数n,代表数据中共有n个待解决的游戏初始状态。
        以下若干行数据分为n组,每组数据有5行,每行5个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。
        对于30%的数据,n<=5;
        对于100%的数据,n<=500。

    输出格式
        输出数据一共有n行,每行有一个小于等于6的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。
        对于某一个游戏初始状态,若6步以内无法使所有灯变亮,请输出“-1”。

    样例输入
    3
    00111
    01011
    10001
    11010
    11100

    11101
    11101
    11110
    11111
    11111

    01111
    11111
    11111
    11111
    11111

    样例输出
    3
    2
    -1



    程序代码
    const
       BigPrime=3214567;
       MaxStep=6;
    type
       pointer=^rec;
       rec=record
             v:longint;
             step:integer;
             next:pointer;
           end;

    var
       total:longint;
       hash:array[0..BigPrime-1]of pointer;
       q:array[1..400000]of rec;

    function update(a:longint;p:integer):longint;
    begin
       a:=a xor (1 shl p);
       if p mod 5<>0 then a:=a xor (1 shl (p-1));
       if (p+1) mod 5<>0 then a:=a xor (1 shl (p+1));
       if p<20 then a:=a xor (1 shl (p+5));
       if p>4 then a:=a xor (1 shl (p-5));
       exit(a);
    end;

    function find(a:longint;step:integer):boolean;
    var
       now:pointer;
    begin
       now:=hash[a mod BigPrime];
       while now<>nil do
       begin
          if now^.v=a then exit(true);
          now:=now^.next;
       end;

       new(now);
       now^.v:=a;
       now^.step:=step;
       now^.next:=hash[a mod BigPrime];
       hash[a mod BigPrime]:=now;
       total:=total+1;
       exit(false);
    end;

    procedure solve;
    var
       p:integer;
       close:longint=0;
       open:longint=1;
    begin
       find(1 shl 25-1,0);
       q[1].v:=1 shl 25-1;
       q[1].step:=0;
       repeat
          inc(close);
          for p:=0 to 24 do
             if not find(update(q[close].v,p),q[close].step+1) and (q[close].step+1<MaxStep) then
             begin
                open:=open+1;
                q[open].v:=update(q[close].v,p);
                q[open].step:=q[close].step+1;
             end;
       until close>=open;
    end;

    procedure print(a:longint);
    var
       now:pointer;
    begin
       now:=hash[a mod BigPrime];
       while now<>nil do
       begin
          if now^.v=a then
          begin
             writeln(now^.step);
             exit;
          end;
          now:=now^.next;
       end;
       writeln(-1);
    end;

    procedure main;
    var
       ch:char;
       i,j,n:integer;
       t:longint;
    begin
       readln(n);
       for i:=1 to n do
       begin
          t:=0;
          for j:=1 to 25 do
          begin
             read(ch);
             t:=t*2+ord(ch)-48;
             if j mod 5=0 then readln;
          end;
          print(t);
          if i<n then readln;
       end;
    end;

    begin
       solve;
       main;
    end.


    =======================  性感的分割线  =======================


    Problem : garden / 和MM逛花园

    题目来源
        07年Matrix67生日邀请赛第四题

    问题描述
        花园设计强调,简单就是美。Matrix67常去的花园有着非常简单的布局:花园的所有景点的位置都是“对齐”了的,这些景点可以看作是平面坐标上的格点。相邻的景点之间有小路相连,这些小路全部平行于坐标轴。景点和小路组成了一个“不完整的网格”。
        一个典型的花园布局如左图所示。花园布局在6行4列的网格上,花园的16个景点的位置用红色标注在了图中。黑色线条表示景点间的小路,其余灰色部分实际并不存在。
            

        Matrix67 的生日那天,他要带着他的MM在花园里游玩。Matrix67不会带MM两次经过同一个景点,因此每个景点最多被游览一次。他和他
  • 相关阅读:
    Java三大特性与实战
    Java数组
    Java流程控制,for,switch,while.break,continue,return
    洛谷——P1498 南蛮图腾
    洛谷——P1010 幂次方
    洛谷——P1147 连续自然数和
    洛谷——P1514 引水入城
    洛谷——1538 迎春舞会之数字舞蹈
    普及练习场之排序Ex
    普及练习场之排序
  • 原文地址:https://www.cnblogs.com/by-1075324834/p/4464509.html
Copyright © 2011-2022 走看看