【DFS】codeforces B. Sagheer, the Hausmeister

http://codeforces.com/contest/812/problem/B

【题意】

有一个n*m的棋盘,每个小格子有0或1两种状态,现在要把所有的1都变成0,问最少的步数是多少?初始位置在左下角,只有把下面一层的1都变成0后才可以到上一层,只有在每层的最右边和最左边可以向上走(up),否则只能左右移动(left or right)。只要经过1,就可以把1变成0,只要把最后一个1,就可以立即停止操作。

【Accepted】

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <cmath>
  4 #include <vector>
  5 #include <algorithm>
  6 #include <set>
  7 #include <map>
  8 #include <queue>
  9 #include <deque>
 10 #include <stack>
 11 #include <string>
 12 #include <bitset>
 13 #include <ctime>
 14 #include<algorithm>
 15 #include<cstring>
 16 using namespace std;
 17 int n,m;
 18 const int maxn=1e2+5;
 19 char s[maxn];
 20 int a[16][maxn];
 21 int sum[16];
 22 int ans;
 23 int fir[16];
 24 int sec[16];
 25 const int inf=0x3f3f3f3f;
 26 int index;
 27 void dfs(int cur,int flag,int cnt)
 28 {
 29     if(cur==index)
 30     {
 31         if(flag)
 32         {
 33             int t=cnt+sec[index]-1;
 34             ans=min(ans,t);
 35             return;
 36         }
 37         else
 38         {
 39             int t=cnt+m+2-fir[index];
 40             ans=min(ans,t);
 41             return; 
 42         }
 43     }
 44     if(flag)
 45     {
 46         if(sum[cur])
 47         {
 48             dfs(cur-1,0,cnt+m+2);
 49             dfs(cur-1,1,cnt+2*(sec[cur]-1)+1);
 50         }
 51         else
 52         {
 53             dfs(cur-1,1,cnt+1);
 54         }
 55     }
 56     else
 57     {
 58         if(sum[cur])
 59         {
 60             dfs(cur-1,1,cnt+m+2);
 61             dfs(cur-1,0,cnt+2*(m+2-fir[cur])+1);
 62          } 
 63          else
 64          {
 65              dfs(cur-1,0,cnt+1);
 66          }
 67     }
 68     
 69 }
 70 int main()
 71 {
 72     while(~scanf("%d%d",&n,&m))
 73     {
 74         memset(sum,0,sizeof(sum));
 75         memset(fir,-1,sizeof(fir));
 76         memset(sec,0,sizeof(sec));
 77         ans=inf;
 78         for(int i=1;i<=n;i++)
 79         {
 80             scanf("%s",s+1);
 81             for(int k=1;k<=m+2;k++)
 82             {
 83                 a[i][k]=s[k]-'0';
 84                 sum[i]+=a[i][k];
 85                 //每层最右的1的位置 
 86                 if(a[i][k])
 87                 {
 88                     sec[i]=k;
 89                 }
 90                 //每层最左的1的位置 
 91                 if(a[i][k]&&fir[i]==-1)
 92                 {
 93                     fir[i]=k;
 94                 }
 95             }
 96          } 
 97          int cou=0;
 98          //index表示走到第几层为止,因为上面的都是0 
 99          index=0;
100          for(int i=1;i<=n;i++)
101          {
102             cou+=sum[i];
103             if(cou!=0)
104             {
105                 index=i;
106                 break;
107             }
108          }
109          //特判,如果数据都是0 
110          if(index==0)
111          {
112              printf("0\n");
113              continue;
114           } 
115           //分别表示第几层,当前层的初始位置在最左边还是最右边,步数 
116         dfs(n,1,0);
117         cout<<ans<<endl; 
118     }
119     return 0;
120 }
DFS:2^15

时间复杂度是2^15

没有考虑的都是0的corner case,疯狂wa

posted @ 2017-06-02 09:07  shulin15  阅读(250)  评论(0编辑  收藏  举报