标签:
给你一个
首先我们看到这么小的
然后就是如何暴力了。
首先我们先处理出每一个联通块,并且求出每个联通块旋转可以得到的所有联通块(要去重,不然会
然后我们将所有的联通块按大小排序,从大到小暴力枚举就行了。
#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;
}
标签:
原文地址:http://blog.csdn.net/qq_21995319/article/details/45743409