城堡——搜索,稍微有点水,令人惊异的是被洛谷评为提高+

  此题在Openjudge NOI 上面还有一个阉割版,也就是只求最大房间大小和房间总数量,在2.5搜索专题里面。阉割版不需要多思考就可以做出来,不过原版也只是在想一步而已,鉴于数据不是特别大。可以看到我的做法就是先BFS 算房间,把每个块所属的房间和大小记录好,然后再 按 顺 序 枚举每个块,从而得出做大合并房间和推倒位置。判断墙的存在时用了位运算,因为题目的1248明显就是暗示要这么搞最方便。

 1 #include<queue>
 2 #include<iostream>
 3 using namespace std;
 4 const int N=64,ax[]={0,0,1,-1,0},ay[]={0,-1,0,0,1},dr[]={0,1,8,2,4};
 5 const char conv[]={‘\0‘,‘W‘,‘S‘,‘N‘,‘E‘};
 6 struct pnt{int x,y;pnt(int n1,int n2):x(n1),y(n2){}};
 7 int r,c,arg[N][N];
 8 int rooms=1,largest,ans,fnx,fny,fnd,size[N],code[N][N];
 9 bool bfsed[N][N];
10 int bfs(int sx,int sy){
11     int res=1;
12     queue<pnt> q;
13     q.push(pnt(sx,sy));
14     bfsed[sx][sy]=true;
15     code[sx][sy]=rooms;
16     while(!q.empty()){
17         int x=q.front().x,y=q.front().y;
18         q.pop();
19         for(int i=1;i<=4;i++){
20             int nx=x+ax[i],ny=y+ay[i];
21             if(nx<1||nx>r||ny<1||ny>c||bfsed[nx][ny]||arg[x][y]&dr[i])continue;
22             res++;
23             bfsed[nx][ny]=true;
24             code[nx][ny]=rooms;
25             q.push(pnt(nx,ny));
26         }
27     }
28     return res;
29 }
30 int main(){
31     cin>>c>>r;
32     for(int i=1;i<=r;i++)
33         for(int j=1;j<=c;j++)
34             cin>>arg[i][j];
35     for(int i=1;i<=r;i++)
36         for(int j=1;j<=c;j++)
37             if(!bfsed[i][j])
38                 largest=max(largest,size[rooms]=bfs(i,j)),rooms++;
39     for(int j=c;j>=1;j--)
40         for(int i=1;i<=r;i++){
41             if(i>1&&(arg[i][j]&2)&&code[i][j]!=code[i-1][j]){
42                 if(size[code[i-1][j]]+size[code[i][j]]>=ans){
43                     ans=size[code[i-1][j]]+size[code[i][j]];
44                     fnx=i;fny=j;fnd=3;
45                 }
46             }
47             else if(j<c&&(arg[i][j]&4)&&code[i][j]!=code[i][j+1]){
48                 if(size[code[i][j+1]]+size[code[i][j]]>=ans){
49                     ans=size[code[i][j+1]]+size[code[i][j]];
50                     fnx=i;fny=j;fnd=4;
51                 }
52             }
53         }
54     cout<<rooms-1<<endl<<largest<<endl<<ans<<endl
55         <<fnx<<" "<<fny<<" "<<conv[fnd]<<endl;
56     return 0;
57 }

Method_01

  洛谷上3ms。

时间: 2024-10-06 19:02:44

城堡——搜索,稍微有点水,令人惊异的是被洛谷评为提高+的相关文章

搜索复习-基础水题

tyvj1080 N皇后 描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 列号  1  2  3  4  5  6 ------------------------- 1 |  | O |  |  |  |  | ------------------------- 2 |  |  |  | O |  |  | ------------------------- 3 |  |  |  |  |

洛谷P2661 信息传递 类似tarjan 强连通 灌水

洛谷P2661 信息传递类似tarjan 强连通 灌水 题意 求一个特殊的图的最小环 这个图 有一个性质 每个点只有一条出边 这样满足一个性质,一张图只有 一个环,以及别的连向他们的边都是一些连向 或者 间接连向这个环的树枝 这些树枝一定不会连成环,因为 每个点只有一条出边,而不可能有两条,所以只要把这些树枝边都删掉,然后再类似tarjan一样跑一遍灌水就行了 先说一下思路,这整道题就是给你几个带枝叶的环要你求最短环而已,于是在输入的时候可以把图中每个点的入度记录下来,然后再删除那些入度为0的点

【日常学习】【搜索/排序+字符串】洛谷1012/1107 最大整数题解

转载请注明出处 [ametake版权全部]http://blog.csdn.net/ametake欢迎来看 洛谷1107 最大整数 本题地址:http://www.luogu.org/problem/show?pid=1107 题目描写叙述 设有n个正整数 (n<=20), 将它们连接成一排,  组成一个最大的多位整数. 比如: n=3时, 3个整数13, 312, 343连接成的最大整数为: 34331213 又如: n=4时, 4个整数7,13,4,246连接成的最大整数为: 7424613

洛谷P1118 [USACO06FEB]数字三角形 搜索

洛谷P1118 [USACO06FEB]数字三角形Backward Digit Su-     搜索 这题我们发现每一个位置的加权就是 杨辉三角 yh[ n ][ i ] 然后我们就可以求 n! 暴力 ,但是会 TLE 额 好像是会T 因为12! 已经 4亿了然后我们加一个强力剪枝 如果当前求出来的 s 已经大于 sum了,因为没有负的加权,也就是说这一路是没有用了的,在继续搜下去也不能更新答案了,那么就直接退出 . 1 #include <cstdio> 2 #include <cma

洛谷 P1461海明码 Hamming Codes 枚举 搜索

洛谷 P1461海明码 Hamming Codes枚举 搜索 1 #include <bits/stdc++.h> 2 using namespace std ; 3 4 const int N = 11 ; 5 int mx,B,n,D ; 6 int bin[N] ; 7 struct base{ 8 bool f[ N ] ; 9 inline void clear() { 10 for(int i=1;i<N;i++) f[ i ] = 0 ; 11 } 12 inline vo

洛谷 P1219 八皇后【经典DFS,温习搜索】

P1219 八皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6 列号 2 4 6 1 3 5 这只是跳棋放置的一个解.请编一个程序找出所有跳棋放置的解.并把它们以上面的序列方法输出.解按字典顺序排列.请输出前3个解.最后一行是解的总个数. //以下的

洛谷P1019单词接龙 搜索

洛谷P1019 单词接龙 这道题目 我用的是搜索 应为起点已经确认了,那就从这开始搜索,如果能接上去就接上去,回溯一下需要注意的就是一些细节问题,比方说不能被另一个单词完全覆盖等等 以及字符串是从零开始的问题 1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <a

洛谷 P1223 排队接水(贪心,桶排序)

此题为洛谷普及试炼场的一道水题.... 题目链接:https://www.luogu.org/problem/show?pid=1223 题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小. 输入输出格式 输入格式: 输入文件共两行,第一行为n:第二行分别表示第1个人到第n个人每人的接水时间T1,T2,-,Tn,每个数据之间有1个空格. 输出格式: 输出文件有两行,第一行为一种排队顺序,即1到n的一种排列:第二行为

洛谷P2327 [SCOI2005]扫雷 枚举 搜索

洛谷P2327 [SCOI2005]扫雷 枚举 搜索 对搜索的 一些优化 其实我们只要枚举第一行是否有地雷,根据第1行探测出的地雷数,就可以推出第二行是否有地雷 然后在根据第二行探测地雷数推出第三行的情况,这样以此类推,一直推到第 n-1 的探测结果,然后 推出第 n 行是否有地雷如果在推的过程中 使得当前的探测地雷数为 负数 ,说明这个方法是萎的, 或者这一行推完了之后,还是有雷,那也退出,最后还要判断一下第 n 行是否有地雷 1 #include <cstdio> 2 #include &