• POJ 3220 位运算+搜索


    转载自:http://blog.csdn.net/lyhypacm/article/details/5813634

    DES:相邻的两盏灯状态可以互换,给出初始状态。询问是否能在三步之内到达。如果能的话。输出不属。超出3步就输出more。

    貌似典型应用是位压缩。我觉得各种按位运算用的也很巧妙。判断两盏灯是不是状态一样的时候,和交换状态的时候。先广搜一遍,保存到达各种状态的最短路径,然后查询就可以了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<string>
     6 #include<queue>
     7 using namespace std;
     8 const int maxn=1<<16;
     9 
    10 int visi[maxn];
    11 //两点相连,一共有32条边
    12 int a[32][2]={{1,2},{3,4},{5,6},{7,8},{9,10},{11,12},{13,14},{15,16},{1,3},{2,4},{5,7},{6,8},{9,11},{10,12},{13,15},{14,16},
    13        {1,5},{2,6},{3,7},{4,8},{9,13},{10,14},{11,15},{12,16},{1,9},{2,10},{3,11},{4,12},{5,13},{6,14},{7,15},{8,16}};
    14 
    15 void BFS(int p)
    16 {
    17     int i;
    18     visi[p]=0;
    19     queue <int> mq;
    20     mq.push(p);
    21     while(!mq.empty())
    22     {
    23         int t=mq.front();
    24         mq.pop();
    25         if(visi[t]>=3)  continue;
    26         for(i=0;i<32;i++)   //看下可以改变哪两个点
    27         {
    28             int p1,p2;
    29             //表示a[i]灯的状态
    30             p1=t&(1<<(a[i][0]-1));
    31             p2=t&(1<<(a[i][1]-1));
    32             if(p1==p2 || p1&&p2) continue;  //两个灯状态一样
    33             p1=t^(1<<(a[i][0]-1));
    34             p2=p1^(1<<(a[i][1]-1));  //两个灯交换状态
    35             if(visi[p2]==-1)  //如果是其它的值,说明此时步骤不是最小的
    36             {
    37                 mq.push(p2);
    38                 visi[p2]=visi[t]+1;
    39             }
    40         }
    41     }
    42 }
    43 
    44 int main()
    45 {
    46     int tes;
    47     int x,i,j;
    48     x=(1<<16)-(1<<8);   //就是最终状态作为起始状态
    49     memset(visi,-1,sizeof(visi));
    50     BFS(x);
    51     scanf("%d",&tes);
    52     for(i=1;i<=tes;i++)
    53     {
    54         int sum=0;   //表示状态
    55         for(j=0;j<16;j++)
    56         {
    57             int tmp;
    58             scanf("%d",&tmp);
    59             if(tmp==1)
    60                 sum+=1<<j;
    61         }
    62 
    63         printf("Case #%d: ",i);
    64         if(visi[sum]==-1)   //表示三步之内没达到
    65             puts("more");
    66         else printf("%d
    ",visi[sum]);
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    poj2104 Kth-Number
    bzoj2120 数颜色
    hdu5145 NPY and girls
    bzoj2734 集合选数
    bzoj3732 NetWork
    bzoj2152 聪聪可可
    hdu2036(多边形面积)
    超大次幂思路
    hdu 2030 统计汉字个数
    Hibernate 配置文件与映射文件 总结
  • 原文地址:https://www.cnblogs.com/icode-girl/p/4854792.html
Copyright © 2020-2023  润新知