码迷,mamicode.com
首页 > 其他好文 > 详细

sgu-243 Broken Chessboard

时间:2015-05-15 13:40:16      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:

给你一个20?20的桌面,上面有一些用不同字母标号的联通块,联通块可以旋转90,180,270度,(为’.’则表示是桌子)。已知这些联通块是由一个N?N,(N<=5)的网格拆开得到的,要你求出一种拼接方案拼出N?N的网格。

解题思路:

首先我们看到这么小的N,明显是暴力。
然后就是如何暴力了。
首先我们先处理出每一个联通块,并且求出每个联通块旋转可以得到的所有联通块(要去重,不然会TLE)。可以用hash去重。
然后我们将所有的联通块按大小排序,从大到小暴力枚举就行了。

AC代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

int Mod=3307;

struct GG_
{
    int G[7][7];
    int Si[2];
    char le;
    int SS;
}GG[1000]={{{{0}},0,‘\0‘}};

int N;
char ch[30][30]={"\0"};
char help[30][30]={"\0"};
int hash[30][30]={{0}};
int Gp=0;
int go[5][2]={{0,1},{0,-1},{1,0},{-1,0}};
int Minx=2e9,Maxx=-2e9,Miny=2e9,Maxy=-2e9;
bool exist[27][6][6][3320];
char ans[10][10]={"\0"};
int num=0;
bool Ok[30]={0};
int st[30]={0};
int stp=0;

bool cmp(struct GG_ a1,struct GG_ a2)
{return a1.SS>a2.SS || (a1.SS==a2.SS && a1.le<a2.le);}

inline void dfs(int xx,int yy)
{
    GG[Gp].SS++;
    Minx=min(xx,Minx);Miny=min(yy,Miny);
    Maxx=max(xx,Maxx);Maxy=max(yy,Maxy);
    hash[xx][yy]=1;
    for(register int i=0;i<4;i++)
    {
        int xxx=xx+go[i][0],yyy=yy+go[i][1];
        if(xxx>=1 && xxx<=20 && yyy>=1 && yyy<=20 && hash[xxx][yyy]==0)
            if(ch[xx][yy]==ch[xxx][yyy])
                dfs(xxx,yyy);
    }
    return;
}

void Find()
{
    for(register int i=1;i<=20;i++)
        for(register int j=1;j<=20;j++)
        {
            if(hash[i][j]==1) continue;
            if(ch[i][j]!=‘.‘)
            {
                Minx=2e9,Maxx=-2e9,Miny=2e9,Maxy=-2e9;
                Gp++;
                dfs(i,j);
                int hh=0;
                for(register int xx=Minx;xx<=Maxx;xx++)
                {
                    for(register int yy=Miny;yy<=Maxy;yy++)
                    {
                        hh=hh*10%Mod;
                        if(ch[xx][yy]==ch[i][j])
                        {
                            hh=(hh+1)%Mod;
                            GG[Gp].G[xx-Minx+1][yy-Miny+1]=1;
                        }
                    }
                    hh=(hh*10+9)%Mod;
                }
                if(exist[ch[i][j]-‘A‘+1][Maxx-Minx+1][Maxy-Miny+1][hh]==0)
                {
                    exist[ch[i][j]-‘A‘+1][Maxx-Minx+1][Maxy-Miny+1][hh]=1;
                    GG[Gp].Si[0]=Maxx-Minx+1;GG[Gp].Si[1]=Maxy-Miny+1;
                    GG[Gp].le=ch[i][j];
                }
                else
                {
                    memset(GG[Gp].G,0,sizeof(GG[Gp].G));
                    GG[Gp].SS=0;
                    Gp--;
                }
            }
        }
    return;
}

inline bool check(int i,int j,int p)
{
    for(register int xx=1;xx<=GG[p].Si[0];xx++)
        for(register int yy=1;yy<=GG[p].Si[1];yy++)
            if(GG[p].G[xx][yy]==1 && ans[i+xx-1][j+yy-1]!=‘\0‘)
                return false;
    return true;
}

inline void change(int i,int j,int p,char C,int Add)
{
    for(register int xx=1;xx<=GG[p].Si[0];xx++)
        for(register int yy=1;yy<=GG[p].Si[1];yy++)
            if(GG[p].G[xx][yy]==1)
                ans[i+xx-1][j+yy-1]=C,num+=Add;
    return;
}

inline void get_ans(int now)
{
    if(num==N*N)
    {
        for(register int i=1;i<=N;i++)
            puts(ans[i]+1);
        exit(0);
    }
    if(now>stp) return;
    for(int p=st[now];p<st[now+1];p++)
    {
        if(Ok[GG[p].le-‘A‘+1]==1) continue;
        for(register int i=1;i<=N;i++)
        {
            if(i+GG[p].Si[0]-1>N) break;
            for(register int j=1;j<=N;j++)
            {
                if(j+GG[p].Si[1]-1>N) break;
                if(check(i,j,p)==true)
                {
                    Ok[GG[p].le-‘A‘+1]=1;
                    change(i,j,p,GG[p].le,1);
                    get_ans(now+1);
                    change(i,j,p,‘\0‘,-1);
                    Ok[GG[p].le-‘A‘+1]=0;
                }
            }
        }
    }
    return;
}

int main()
{
    scanf("%d\n",&N);
    for(int i=1;i<=20;i++)
        scanf("%s",ch[i]+1);
    Find();
    for(register int i=1;i<=3;i++)
    {
        memset(hash,0,sizeof(hash));
        for(register int i=1;i<=20;i++)
            for(register int j=1;j<=20;j++)
                help[j][20-i+1]=ch[i][j];
        memcpy(ch,help,sizeof(ch));
        Find();
    }
    sort(GG+1,GG+Gp+1,cmp);
    for(int i=1;i<=Gp;i++)
    {
        if(GG[i].le!=GG[i-1].le)
        {
            stp++;
            st[stp]=i;
        }
    }
    st[stp+1]=Gp+1;
    get_ans(1);
    return 0;
}

sgu-243 Broken Chessboard

标签:

原文地址:http://blog.csdn.net/qq_21995319/article/details/45743409

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!