UPC 6352

题意 是 给一个 n*n 的图 图中的数字代表颜色  上下左右相同颜色可以组成一个块 问 一种颜色的块 和两种颜色的块的个数的最大值

这道题 只求 一种颜色 的 块  可以直接深搜 

求两种颜色的块 就需要 想一蛤 , 当然我们可以枚举每两种颜色然后进行深搜,但是复杂度会很高 , 题目还限制了颜色的数的范围是 10 的六次方, 好像可以搞一搞 可以开两个 1e6 的循环 ???  这时候需要 剪枝 一蛤 ,会发现有很多两种颜色的情况 是不需要跑深搜的  如果 cnt i + cnt j <= ans (当前的ans) 的话我们可以直接退出循环 (不是continue !!!),然后 这个 剪枝很优秀,我们还可以对 每种颜色的cnt进行从大到小, 所有后面小的基本不可能会跑第二个循环 所以 就可以很快的求出来

代码 (不要看代码长, 其实 非常非常简单。。。)

#include<bits/stdc++.h>
using namespace std;
const int N = 255;
const int M = 1e6;
int a[N][N],vis[N][N];
int n;
struct node
{
    int cnt,id;
}p[ M + 10 ];
int c[4][2] = {0,1,0,-1,1,0,-1,0};
void dfs1(int x, int y, int cl ,int &tot)
{
    vis[x][y] = 1;
    tot++;
    for(int i=0;i<4;i++) {
        int xx = x + c[i][0];
        int yy = y + c[i][1];
        if(xx < 1 || xx > n || yy < 1 || yy > n) continue;
        if(vis[xx][yy] || a[xx][yy] != cl) continue;
        dfs1(xx,yy,cl,tot);
    }
}

void dfs2(int x,int y,int c1,int c2,int &tot)
{
    vis[x][y] = 1;
    tot++;
    for(int i=0;i<4;i++) {
        int xx = x + c[i][0];
        int yy = y + c[i][1];
        if(xx < 1 || xx > n || yy < 1 || yy > n) continue;
        if(vis[xx][yy] || (a[xx][yy] != c1 && a[xx][yy] != c2)) continue;
        dfs2(xx,yy,c1,c2,tot);
    }
}
bool cmp(node a, node b)
{
    return a.cnt > b.cnt;
}
int main()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
        scanf("%d", &a[i][j]);
    for(int i=0;i<=M;i++){
        p[i].id = i;
        p[i].cnt = 0;
    }
    int ans1 = 0, ans2 = 0;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            if(!vis[i][j]) {
                int tot = 0;
                dfs1(i,j,a[i][j],tot);
                ans1 = max(ans1 , tot);
                p[a[i][j]].cnt += tot;
            }
        }
    }

    sort(p,p+M,cmp);
    ans2 = ans1;
    printf("%d\n",ans1);
    //cout<<ans1<<endl;
    for(int i=0;i<=M;i++) {
        for(int j=i+1;j<=M;++j) {
            if(p[i].cnt + p[j].cnt <= ans2) break;
            //cout<<"sddddd"<<endl;
            memset(vis,0,sizeof(vis));
            for(int rr=1;rr<=n;rr++) {
                for(int cc=1;cc<=n;cc++) {
                    if(!vis[rr][cc]) {
                        if(a[rr][cc] == p[i].id || a[rr][cc] == p[j].id) {
                            int tot = 0;
                            dfs2(rr,cc,p[i].id,p[j].id,tot);
                            ans2 = max(ans2,tot);
                            //cout<<ans2<<endl;
                        }
                    }
                }
            }
        }
    }
    printf("%d\n", ans2);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Hrbust_Final/article/details/81388055
UPC