P1457 【城堡 The Castle】

1: 在西面有墙

2: 在北面有墙

4: 在东面有墙

8: 在南面有墙

选择最佳的墙来推倒。有多解时选最靠西的,仍然有多解时选最靠南的。同一格子北边的墙比东边的墙更优先。

用该墙的南邻单位的北墙或西邻单位的东墙来表示这面墙,方法是输出邻近单位的行数、列数和墙的方位("N"(北)或者"E"(东))。

考前就用这道题来复习一下dfs和bfs吧

1.对于这道题,之前就写过,不过没有那两行输出,多了那两行我的LJbfs就超时了

2.这道题也是很考验看题能力的,反正我是看漏了很多条件

3.这道题用位运算可以省去一些不必要的判断。。。

1 int dx[6]={0,1,0,-1};
2 int dy[6]={1,0,-1,0};
3 int a[6]={1,2,4,8};
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 if(fire[i][j]&a[k])

首先附上70分的超时代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int map[2000][2000],fire[2000][2000];
 7 int dx[6]={0,1,0,-1};
 8 int dy[6]={1,0,-1,0};
 9 int a[6]={1,2,4,8};
10 int s,num,ans=1,n,m;
11 void bfs(int p,int q)
12 {
13     int h[2000][3];
14     h[1][1]=p;h[1][2]=q;
15     map[p][q]=1;
16     int head=0,tail=1,x,y;
17     num++;
18     s=1;
19     do
20     {
21         head++;
22         for(int i=0;i<=3;++i)
23         {
24             x=h[head][1]+dx[i];
25             y=h[head][2]+dy[i];
26             if(x>0&&x<=n&&y>0&&y<=m&&map[x][y]==0&&(fire[x][y]&a[i])==0)
27             {
28                 tail++;
29                 s++;
30                 ans=max(ans,s);
31                 map[x][y]=1;
32                 h[tail][1]=x;
33                 h[tail][2]=y;
34             }
35         }
36     }while(head<tail);
37 }
38 int main()
39 {
40     scanf("%d%d",&m,&n);
41     for(int i=1;i<=n;++i)
42     {
43         for(int j=1;j<=m;++j)
44         {
45             scanf("%d",&fire[i][j]);
46             map[i][j]=0;
47         }
48     }
49     for(int i=1;i<=n;++i)
50     {
51         for(int j=1;j<=m;++j)
52         {
53             if(!map[i][j]) bfs(i,j);
54         }
55     }
56     printf("%d\n%d\n",num,ans);
57     int maxx=ans,hang,lie,qiang;
58     for(int j=1;j<=m;++j)
59     {
60         for(int i=n;i>=1;--i)
61         {
62             for(int k=0;k<=3;++k)
63             {
64                 if(k==1||k==2)
65                 {
66                 memset(map,0,sizeof(map));
67                 if(fire[i][j]&a[k])
68                 {
69                     fire[i][j]-=a[k];
70                     if(k==1) fire[i+1][j]-=a[3];
71                     if(k==2) fire[i][j+1]-=a[0];
72                     for(int x=1;x<=n;++x)
73                     {
74                         for(int y=1;y<=m;++y)
75                         {
76                           if(!map[x][y]) bfs(x,y);
77                         }
78                     }
79                     if(ans>maxx)
80                    {
81                         maxx=ans;
82                         hang=i;
83                         lie=j;
84                         qiang=k;
85                     }
86                     fire[i][j]+=a[k];
87                     if(k==1) fire[i+1][j]+=a[3];
88                     if(k==2) fire[i][j+1]+=a[0];
89                 }
90                 }
91             }
92         }
93     }
94     printf("%d\n%d %d ",maxx,hang,lie);
95     if(qiang==1) printf("N");
96     if(qiang==2) printf("E");
97     return 0;
98 }

上面那串可以忽略,着急什么都不想就瞎写

下面附上正解:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int map[2000][2000],fire[2000][2000];
 6 int dx[6]={0,1,0,-1};
 7 int dy[6]={1,0,-1,0};
 8 int a[6]={1,2,4,8};
 9 int num,ans=1,n,m;
10 int c[5000];                              //用来存储连通块的大小
11 int wei[2000][2000];                      //用来存储房间所属连通块 
12 void bfs(int p,int q,int shu)
13 {
14     int h[2000][3];
15     h[1][1]=p;h[1][2]=q;
16     map[p][q]=1;
17     wei[p][q]=shu;
18     int head=0,tail=1,x,y;
19     num++;
20     c[shu]=1;
21     do
22     {
23         head++;
24         for(int i=0;i<=3;++i)
25         {
26             x=h[head][1]+dx[i];
27             y=h[head][2]+dy[i];
28             if(x>0&&x<=n&&y>0&&y<=m&&map[x][y]==0&&(fire[x][y]&a[i])==0)
29             {
30                 tail++;
31                 c[shu]++;
32                 ans=max(ans,c[shu]);
33                 map[x][y]=1;
34                 wei[x][y]=shu;
35                 h[tail][1]=x;
36                 h[tail][2]=y;
37             }
38         }
39     }while(head<tail);
40 }
41 int main()
42 {
43     scanf("%d%d",&m,&n);
44     for(int i=1;i<=n;++i)
45     {
46         for(int j=1;j<=m;++j)
47         {
48             scanf("%d",&fire[i][j]);
49             map[i][j]=0;
50         }
51     }
52     int cnt=0;
53     for(int i=1;i<=n;++i)
54     {
55         for(int j=1;j<=m;++j)
56         {
57             if(!map[i][j]) bfs(i,j,++cnt);
58         }
59     }
60     printf("%d\n%d\n",num,ans);
61     int maxx=ans,hang,lie,qiang;
62     for(int j=1;j<=m;++j)
63     {
64         for(int i=n;i>=1;--i)
65         {
66             for(int k=1;k<=2;++k)
67             {
68                 if(fire[i][j]&a[k])
69                 {
70                     if(k==1&&wei[i][j]!=wei[i-1][j]) ans=c[wei[i][j]]+c[wei[i-1][j]];
71                     if(k==2&&wei[i][j]!=wei[i][j+1]) ans=c[wei[i][j]]+c[wei[i][j+1]];
72                     if(ans>maxx)
73                     {
74                         maxx=ans;
75                         hang=i;
76                         lie=j;
77                         qiang=k;
78                     }
79                 }
80             }
81         }
82     }
83     printf("%d\n%d %d ",maxx,hang,lie);
84     if(qiang==1) printf("N");
85     if(qiang==2) printf("E");
86     return 0;
87 }

猜你喜欢

转载自www.cnblogs.com/zytwan/p/9931612.html