1. 程式人生 > >P1457 【城堡 The Castle】

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 }