zoukankan      html  css  js  c++  java
  • [水题]ZOJ3038 Triangle War II

    题意:

    给了这样一张图 有两种状态:pushed(*)和unpushed(.)    为方便起见分别成为 开 和 关

    改变一个点的开关状态 会同时改变与它相邻的点的开关状态  比如改变5,则2、3、4、6、8、9都会改变

    N(行数)最多为6 即 最多21个点

    求: 任意改变开关状态后 最多能有几个关着。

    为什么这么像高斯消元!!!

    每个点的状态只有开和关 总共就只有2^21个状态

    dfs会爆栈!


    所以bfs就行了! 把这些点的开关状态看成二进制 用0到$2^{21}$的数组来标记当前状态有没有出现过

      1 struct node
      2 {
      3     bool a[25];
      4 }front, rear;
      5 queue<node> q;
      6 int ans;
      7 bool vis[2100000];
      8 int biao[]={0, 1, 3, 6, 10, 15, 21};
      9 int b[][2]={
     10             {0,0},
     11             {-1,0},
     12             {-1,-1},
     13             {1,0},
     14             {1,1},
     15             {0,1},
     16             {0,-1}
     17            };
     18 int l[25], c[25][10];
     19 void pre()
     20 {
     21     memset(l, 0, sizeof(l));
     22     for(int i=1;i<=21;i++)
     23     {
     24         int x=0;
     25         while(biao[x]<i)
     26             x++;
     27         int y=i-x*(x-1)/2;
     28         for(int k=0;k<7;k++)
     29         {
     30             int dx=x+b[k][0];
     31             int dy=y+b[k][1];
     32             if(dx>=1 && dx<=6 && dy>=1 && dy<=dx)
     33                 c[i][l[i]++]=dx*(dx-1)/2+dy;
     34         }
     35     }
     36 }
     37 void bfs(int n)
     38 {
     39     int d=0;
     40     for(int i=1;i<=n;i++)
     41         d=(d<<1)+front.a[i];
     42     vis[d]=1;
     43     q.push(front);
     44     while(!q.empty())
     45     {
     46         front=q.front();
     47         q.pop();
     48         for(int i=1;i<=n;i++)
     49             if(!front.a[i])
     50             {
     51                 rear=front;
     52                 for(int j=0;j<l[i];j++)
     53                     rear.a[c[i][j]]=1^front.a[c[i][j]];
     54                 d=0;
     55                 int cnt=0;
     56                 for(int j=1;j<=n;j++)
     57                 {
     58                     d=(d<<1)+rear.a[j];
     59                     if(!rear.a[j])
     60                         cnt++;
     61                 }
     62                 if(!vis[d])
     63                 {
     64                     vis[d]=1;
     65                     ans=max(ans, cnt);
     66                     if(ans==n)
     67                         return ;
     68                     q.push(rear);
     69                 }
     70             }
     71     }
     72 }
     73 int main()
     74 {
     75     pre();
     76     int n;
     77     while(~scanf("%d", &n))
     78     {
     79         ans=0;
     80         for(int i=1;i<=n;i++)
     81             for(int j=1;j<=i;j++)
     82             {
     83                 char ch;
     84                 cin>>ch;
     85                 if(ch=='.')
     86                     ans++;
     87                 front.a[i*(i-1)/2+j]=(ch=='*');
     88             }
     89         n=(n+1)*n/2;
     90         if(ans==n)
     91         {
     92             printf("%d
    ", ans);
     93             continue;
     94         }
     95         while(!q.empty())
     96             q.pop();
     97         memset(vis, 0, sizeof(vis));
     98         bfs(n);
     99         printf("%d
    ", ans);
    100     }
    101     return 0;
    102 }
    ZOJ 3038
  • 相关阅读:
    Ubuntu adb devices :???????????? no permissions (verify udev rules) 解决方法
    ubuntu 关闭显示器的命令
    ubuntu android studio kvm
    ubuntu 14.04版本更改文件夹背景色为草绿色
    ubuntu 创建桌面快捷方式
    Ubuntu 如何更改用户密码
    ubuntu 14.04 返回到经典桌面方法
    ubuntu 信使(iptux) 创建桌面快捷方式
    Eclipse failed to get the required ADT version number from the sdk
    Eclipse '<>' operator is not allowed for source level below 1.7
  • 原文地址:https://www.cnblogs.com/Empress/p/4273175.html
Copyright © 2011-2022 走看看