/ Vijos / 题库 / 海战 /

题解

122 条题解

  • -1
    @ 2017-11-21 15:07:35
    #include <iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    #define FOR(i,x,y) for(i=x;i<=y;++i)
    #define maxa 1000+100
    using namespace std;
    int n,m,ans = 0,b[maxa][maxa],cnt = 0,flag = 0;
    string s[maxa];
    int l1,r1,u,d;
    int l[] = {0,0,1,-1};
    int r[] = {1,-1,0,0};
    void dfs(int x,int y)
    {
        int i;
       FOR(i,0,3)
       {
           int nx = x+r[i];
           int ny = y+l[i];
           if(nx<0||nx>=n||ny<0||ny>=m)
            continue;
           if(s[nx][ny]=='#'&&b[nx][ny]==0){
            b[nx][ny] = 1;
            l1 = min(l1,ny);
            r1 = max(r1,ny);
            u = min(u,nx);
            d = max(d,nx);
             dfs(nx,ny);
           }
       }
    }
    bool check()
    {
        int i,j;
        FOR(i,u,d)
        FOR(j,l1,r1)
        if(b[i][j]==0)
        return true;
        return false;
    }
    int main()
    {
        int i,j;
        memset(b,0,sizeof(b));
        cin>>n>>m;
        FOR(i,0,n-1)
        {
            cin>>s[i];
        }
        FOR(i,0,n-1)
        FOR(j,0,m-1)
            if(s[i][j]=='#'&&b[i][j]==0)
            {
                cnt++;
                b[i][j] =1;
                l1 =r1 = j;
                u = d = i;
                dfs(i,j);
                if(check())
                {
                    cout<<"Bad placement.";
                    return 0;
                }
            }
        cout<<"There are "<<cnt<<" ships."<<endl;
        return 0;
    
    }
    
    
  • -1
    @ 2017-04-12 22:17:17

    也是以前做过的题呢
    做法是找到‘#’进入搜索,把与它相连的所有‘#’都变成除了‘.’以外的字符
    最重要的是搜索同时记录该船所能覆盖到的最远端点
    即船的第一排与最后一排,第一列与最后一列,我这里用maxx minx maxy miny表示
    从搜索中退出后循环这条船覆盖的区域,看有无‘.’(这里也就是为什么上面不变成‘.’)
    有‘.’就bad placement 没有就加ans

    var
        m:array[0..1001,0..1001] of char;
        i,j,k,L,ans,r,c,maxx,maxy,minx,miny:longint;
        
    
    procedure se(i,j:longint);
    begin
        if (i>maxx) then maxx:=i;
        if (i<minx) then minx:=i;
        if (j>maxy) then maxy:=j;
        if (j<miny) then miny:=j;
        m[i,j]:='@';
        if (m[i-1,j]='#') then se(i-1,j);
        if (m[i+1,j]='#') then se(i+1,j);
        if (m[i,j-1]='#') then se(i,j-1);
        if (m[i,j+1]='#') then se(i,j+1);//我比较喜欢拍机械键盘所以就这样多拍拍不用循环了
                                                                        //:P
    end;
    begin
        readln(r,c);
        for i:= 1 to r do
        begin
            for j:= 1 to c do
            begin
                read(m[i,j]);
            end;
            readln;
        end;
        for i:= 1 to r do
        begin
            for j:= 1 to c do
            begin
                if m[i,j]='#' then
                begin
                    maxx:=-1;minx:=1001;
                    maxy:=-1;miny:=1001;
                    se(i,j);
                    for k:= minx to maxx do
                    begin
                        for L:= miny to maxy do
                        begin
                            if m[k,L]='.' then begin writeln('Bad placement.');halt; end;
                        end;
                    end;
                    inc(ans);
                end;
            end;
        end;
        writeln('There are ',ans,' ships.');
    end.
    

信息

ID
1076
难度
5
分类
搜索 | 搜索与剪枝 点击显示
标签
(无)
递交数
3113
已通过
1037
通过率
33%
被复制
10
上传者