HDU 5925 Coconuts(二维离散化权值统计 经典)

题目链接

这是2016 ccpc 东北的银牌题,很经典.
Coconuts

分析

直接二维离散化,然后记录下各压缩了多少行和列,将其权值相乘便是离散化的图里的权重. dfs or bfs 统计一下就行了.

//Problem : 5925 ( Coconuts )     Judge Status : Accepted
//RunId : 22331126    Language : G++    Author : zouzhitao
//Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta
#include
#define pb push_back
#define mp make_pair
#define PI acos(-1)
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define INF64 0x3f3f3f3f3f3f3f3f
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define ms(x,v) memset((x),(v),sizeof(x))
#define eps 1e-8
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef long double DB;
typedef pair<int,int> Pair;
const int maxn = 400+10;

std::map<int, int> idx_x,idx_y;

LL vx[maxn],vy[maxn];
int a[maxn][maxn];
std::vector ans;
int x[maxn],y[maxn];

Pair bad[maxn];

int lishan(int * arr,int len, LL *val,std::map<int, int>& m ){
    m.clear();
    sort(arr,arr+len);
    len = unique(arr,arr+len)-arr;
    int t =1;
    val[t] = 1;
    m[arr[0]] = t++;
    for(int i=1 ; iif(arr[i]!=arr[i-1]+1)val[t++] = arr[i] - arr[i-1]-1;//补空白
        val[t] =1;m[arr[i]] = t++;
    }
    return t;
}
int dx[] = {1,0,0,-1};
int dy[] = {0,1,-1,0};
int vis[maxn][maxn];
LL bfs(int i,int j) {
    queue Q;
    Q.push(mp(i,j));
    vis[i][j] =1;
    LL cnt =0;
    while (!Q.empty()) {
        Pair p = Q.front();Q.pop();
        cnt += vx[p.fi] * vy[p.se];
        for(int i=0 ; i<4 ; ++i){
            int ni = p.fi + dx[i];
            int nj = p.se+dy[i];
            if(!a[ni][nj] && !vis[ni][nj]){
                vis[ni][nj] =1;
                Q.push(mp(ni,nj));
            }
        }
    }
    return cnt;
}


int main()
{
    // ios_base::sync_with_stdio(0);
    // cin.tie(0);
    // cout.tie(0);

    int T;
    cin>>T;

    for(int kase =1 ; kase <=T ; ++kase){
        int n,m,k;
        cin>>n>>m>>k;
        for(int i=1 ; i<=k ; ++i){
            scanf("%d%d",&bad[i].fi, &bad[i].se );
            x[i] = bad[i].fi;y[i] = bad[i].se;
        }
        x[0] = 1;x[k+1] = n;
        y[0] = 1;y[k+1] = m;
        n = lishan(x,k+2,vx,idx_x);
        m = lishan(y,k+2,vy,idx_y);
        ms(a,0);
        for(int i=1;  i<=k ; ++i)a[idx_x[bad[i].fi]][idx_y[bad[i].se]] = 1;
        for(int i=0 ; i<=m ; ++i)a[0][i] = a[n][i] =1;
        for(int i=0 ; i<=n ; ++i)a[i][0] = a[i][m] =1;
        // std::cout << "val" << '\n';
        // for(int i=0 ; i<=n; ++i){
        //     for(int j=0 ; j<=m ; ++j)std::cout << vx[i]*vy[j] << ' ';std::cout << '\n';
        // }
        // std::cout << "mat" << '\n';
        // for(int i=0 ; i<=n ; ++i){
        //     for(int j=0 ; j<=m ; ++j)std::cout << a[i][j] << ' ';std::cout << '\n';
        // }
        // std::cout << "vx vy" << '\n';
        // for(int i=0 ; i<=n ; ++i)std::cout << vx[i] << ' ';std::cout  << '\n';
        // for(int i=0 ; i<=m ; ++i)std::cout << vy[i] << ' ';std::cout  << '\n';
        ms(vis,0);
        ans.clear();
        for(int i=1 ; ifor(int j=1 ; jif(!a[i][j] && !vis[i][j])ans.pb(bfs(i,j));
            }
        }
        printf("Case #%d:\n",kase );
        sort(ans.begin(),ans.end());
        printf("%d\n",ans.size() );
        for(unsigned int i=0 ; iprintf("%lld%c",ans[i],i==ans.size()-1?'\n':' ' );
        }
    }

    return 0;
}

你可能感兴趣的:(算法刷题)