SRM340 VegetableGarden

Description

你的蔬菜园形成了一个矩形网格。你决定检查一些小块土地。从左上角开始,你将走过菜园,回到起点。现在你想要检查一下菜园内的田地,于是你决定从左上角出发,在菜园里走一圈回到原处。最后,所有在你走过的这个环内的田地都被认为检查过了。为了保护植 物,你的路径只能在田地边界的小路上走,不能走到田地里面。并且你走过的路径不能自交,小路保证足够宽,你可以多次沿着一条小路走,并且这些路径都不相 交。先在给你菜园的地图,其中有的田地标记为”I”,表示这些田地是你想要检查的;有的田地被标记为”X”,表示这些田地是你不想检查的;有的田地被标记为”.”,表示这些田地你不关心。假设菜园中有K个”I”,那么你要返回K个数字,其中第i个数为:恰好检查任意i个标记为”I”的田地,并且没有检查任何一个标记为”X”的田地的最短路。

【输入格式】
n 行,每行 m 个字符。
'I'表示重要的格子,'X'表示有坏处的格子,'.'表示其他格子。
【输出格式】
输出重要的格子数行,第 i 行表示圈住 i 个重要的格子的最小
路径长度。
【输入样例】
X.I
.I.
I..
【输出样例】
8
10
14

判断一个格子是否被圈住,可以看它上面是否有奇数条边

如果是奇数,那么就需要从下面连回起点

用$dist[x][y][S]$表示到$(x,y)$,关键点上面的边数的奇偶性状态S

广搜更新$dist$数组

复杂度$O(n^{2}*10*2^{10})$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<queue>
 7 using namespace std;
 8 struct ZYYS
 9 {
10   int x,y,s;
11 };
12 const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
13 int n,m,cnt,x[11],y[11],pd[11],dist[51][51][1<<11],ans[11],inf,tot,Max;
14 bool vis[51][51][1<<11];
15 char s[51][51];
16 queue<ZYYS>Q;
17 int get(int S,int xx,int yy)
18 {int i;
19   for (i=1;i<=cnt;i++)
20     {
21       if (yy==y[i]&&xx<=x[i]) S^=(1<<i-1); 
22     }
23   return S;
24 }
25 int main()
26 {int i,j;
27   while (~scanf("%s",s[n]))
28      {
29        n++;
30     }
31   m=strlen(s[0]);
32    for (i=0;i<n;i++)
33      for (j=0;j<m;j++)
34     {
35       if (s[i][j]=='X')
36         {
37           ++cnt;
38           pd[cnt]=0;
39           x[cnt]=i;y[cnt]=j;
40         }
41       else if (s[i][j]=='I')
42         {
43           ++cnt;
44           pd[cnt]=1;
45           x[cnt]=i;y[cnt]=j;
46         }
47     }
48   memset(dist,127/2,sizeof(dist));
49   Q.push((ZYYS){0,0,0});
50   dist[0][0][0]=0;
51   while (Q.empty()==0)
52     {
53       ZYYS u=Q.front();
54       Q.pop();
55       vis[u.x][u.y][u.s]=0;
56       for (i=0;i<4;i++)
57     {
58       int x=u.x+dx[i],y=u.y+dy[i],S;
59       if (x<0||y<0||x>n||y>m) continue;
60       if (i==0||i==1)
61         S=get(u.s,u.x,min(y,u.y));
62       else S=u.s;
63       if (dist[x][y][S]>dist[u.x][u.y][u.s]+1)
64         {
65           dist[x][y][S]=dist[u.x][u.y][u.s]+1;
66           if (vis[x][y][S]==0)
67         {
68           vis[x][y][S]=1;
69           Q.push((ZYYS){x,y,S});
70         }
71         }
72     }
73     }
74   memset(ans,127/2,sizeof(ans));
75   inf=ans[0];
76   for (i=1;i<(1<<cnt);i++)
77     {
78       tot=0;
79       for (j=1;j<=cnt;j++)
80     if ((i&(1<<j-1)))
81       {
82         if (pd[j]==0)
83           {
84         tot=-1;
85         break;
86           }
87         else 
88           tot++;
89       }
90       if (tot!=-1)
91     {
92       Max=max(tot,Max);
93       if (dist[0][0][i]<ans[tot]) ans[tot]=dist[0][0][i];
94     }
95     }
96   for (i=1;i<=Max;i++)
97     printf("%d\n",ans[i]);
98 }

 

posted @ 2018-03-20 16:27  Z-Y-Y-S  阅读(355)  评论(0编辑  收藏  举报