Codevs 1536 海战 (DFS || BFS)+判断

题目:海战

题解:

嗯……不判断船只形状的是“细胞计数”,读入图后再遍历一遍图,如果遇到‘#’,ans++,把以这个‘#’为起点拓展节点,如果是‘#’都变为‘.’;
判断船只形状方法:设遇到的‘#’为矩形左上角p,如果拓展是点next,那如果 next.x < p.x || next.y <p.y 就是不合法的 ,即有点跑到了p的上面或左面,显然矩形不会这样。还有一种情况,如果矩形不全,如:

***
***
**

这种情况也是不合法的,判断方法,拓展时用变量max_x,max_y表示矩形最底一行是哪一行,最右一列是哪一列,这样这个矩形应该有
sum = (max_x - x+1) * (max_y - y) 个‘’,再用一个cnt 记录一下实际bfs时找到了多少了‘’,如果合法那么sum == cnt, else sum!= cnt。

代码:

#include 
#include 
#include 
#include 
#define haha (puts("haha");)
using namespace std;

const int MAXN = 1000 + 50;
int R, C;
char maps[MAXN][MAXN];
bool vis[MAXN][MAXN];
int dx[] = {0,0,1,0,-1};
int dy[] = {0,1,0,-1,0};
struct Point{
    int x, y;
};

queue  q;
bool bfs(int x, int y)
{
//  cout << x << " *************** " << y << endl;
    int xmax = -1, ymax = -1;
    int cnt = 0;
    q.push((Point){x,y});
    maps[x][y] = '.';
    while(q.size())
    {
        Point p = q.front();
        q.pop();
        if(p.x < x && p.y < y)
            return 0;
        xmax = max(xmax,p.x);
        ymax = max(ymax,p.y);
        cnt ++;
        for(int i = 1; i <= 4; i ++)
        {
            int nx = p.x + dx[i];
            int ny = p.y + dy[i];
            if(nx >= 1 && nx <= R && ny >= 1 && ny <= C && maps[nx][ny] == '#')
            {
                q.push((Point){nx,ny});
                maps[nx][ny] = '.';
            }
        }
    }
    x--;y--;
    int sum = (xmax - x) * (ymax - y);
//  cout << cnt << " " << sum << endl; 
    if(cnt != sum)
        return 0;
    else return 1;
}

int main()
{
    int ans = 0;
    cin >> R >> C;
    for(int i = 1; i <= R; i ++){
        for(int j = 1; j <= C; j ++){
            cin >> maps[i][j];
        }
    }
    for(int i = 1; i <= R; i ++)
        for(int j = 1; j <= C; j ++)
            if(maps[i][j] == '#')
                if(bfs(i,j))
                    ans ++;
                else {
                    printf("Bad placement.\n");
                    return 0;
                }
    printf("There are %d ships.\n",ans);
    return 0;
}

/*
这是不合法的样例1:
6 8
........
........
..####..
...###..
...###..
........

*/

/*
这是不合法的样例2:
6 6
.....#
##...#
##...#
..#..#
.....#
######

*/
以上:2016-07-29 22:23

重打:

#include 
#include 
#include 
#include 
using namespace std;

const int MAXN = 1000 + 10;
const int INF = 1e9;
const int dx[] = {0,0,1,0,-1};
const int dy[] = {0,-1,0,1,0};
int R, C, ans = 0;
int xx, yy, max_x = -INF, max_y = -INF, cnt;
char maps[MAXN][MAXN];

void dfs(int x, int y, bool t = 1)
{
    if(!t)
    {
        ans ++;
        max_x = -INF; max_y = -INF;
        xx = x; yy = y;
        cnt = 0;
    }
    maps[x][y] = '.';
    cnt ++;
    max_x = max(max_x, x);
    max_y = max(max_y, y);
    for(int i = 1; i <= 4; i ++)
    {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if(nx >= 0 && nx <= R && ny >= 0 && ny <= C && maps[nx][ny] == '#')
        {
            if(nx < xx || ny < yy)
            {
                ans = -1;
                return;
            }
            dfs(nx, ny);
        }
    }
    if(!t && cnt < (max_x-xx+1)*(max_y-yy+1))
        ans = -1;
}

int main()
{
    cin >> R >> C;
    for(int i = 1; i <= R; i ++)
        for(int j = 1; j <= C; j ++)
        {
            char c = getchar();
            while(c != '.' && c != '#')
                c = getchar();
            maps[i][j] = c;
        }
    for(int i = 1; i <= R; i ++)
        for(int j = 1; j <= C; j ++)
            if(maps[i][j] == '#' && ans != -1)
                dfs(i,j,0);
    if(ans != -1)
        printf("There are %d ships.", ans);
    else printf("Bad placement.\n");
    return 0;
}
以上:2016-9-28 16:43:04

当时居然用 BFS 做的, 还有 辣么丑,naive。
这次跑的比第一次快。
进步-开心!

你可能感兴趣的:(搜索)