【NOI2005】智慧珠游戏
搜索
题目大意:
给定一个三角形,每个点是一个空位。现在有 $12$ 个形状不同的零件,要放到三角形里且需要恰好完全覆盖。
现在给出初始状态,问合法的解。保证解不超过一个。
题解:
暴力搜索。
先把智慧珠可能的 $60$ 种摆法预处理出来(可以通过初始状态进行变换,也可以直接打表)。
然后搜索,每次找到最上面,最左边的空格,考虑用一种方法填充。枚举即可。
我们来剪枝。
发现如果有大小为 $1,2,6$ 的连通块,那么显然是不存在解的。所以可以每次用并查集求出所有连通块大小,然后如果出现 $1,2,6$ 则直接退出当前递归。
加上这个剪枝就可以通过辣!
打表的代码,$6\rm KB$ 左右,行数超过五百。感觉也不多。
Code:
/*
By mrsrz
500+ lines
2019-10-17
*/
#include<iostream>
#include<cstdlib>
using namespace std;
struct block{
int r,c;
bool b[11][11];
char ch;int y;
}b[100];
char mp[11][11];
bool use[127];
int Id[11][11],tot;
inline bool can_put(int r,int c,int id){
if(c<0)return 0;
for(int i=0;i<b[id].r;++i){
for(int j=0;j<b[id].c;++j)
if(b[id].b[i][j]){
int x=r+i,y=c+j;
if(x>=10||y>x)return 0;
if(mp[x][y]!='.')return 0;
}
}
return 1;
}
inline void fill(int r,int c,int id){
for(int i=0;i<b[id].r;++i){
for(int j=0;j<b[id].c;++j)
if(b[id].b[i][j]){
int x=r+i,y=c+j;
mp[x][y]=b[id].ch;
}
}
}
inline void clear(int r,int c,int id){
for(int i=0;i<b[id].r;++i){
for(int j=0;j<b[id].c;++j)
if(b[id].b[i][j]){
int x=r+i,y=c+j;
mp[x][y]='.';
}
}
}
int fa[121],sz[121];
bool vs[121];
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void judge(){
for(int i=1;i<=tot;++i)fa[i]=i,sz[i]=1,vs[i]=0;
for(int i=0;i<10;++i)
for(int j=0;j<=i;++j)if(mp[i][j]=='.'){
int u=find(Id[i][j]);
if(j-1>=0&&mp[i][j-1]=='.'){
int v=find(Id[i][j-1]);
if(u!=v)sz[u]+=sz[v],fa[v]=u;
}
if(i-1>=j&&mp[i-1][j]=='.'){
int v=find(Id[i-1][j]);
if(u!=v)sz[u]+=sz[v],fa[v]=u;
}
}else fa[Id[i][j]]=0,sz[Id[i][j]]=0;
for(int i=1;i<=tot;++i)
if(i==find(i))vs[sz[i]]=1;
}
void dfs(char nw){
if(nw==12){
for(int i=0;i<10;++i)
cout<<mp[i]<<'\n';
exit(0);
}
judge();
if(vs[1]||vs[2]||vs[6])return;
int xx=-1,yy=-1;
for(int i=0;i<10&&xx==-1;++i)
for(int j=0;j<=i;++j)
if(mp[i][j]=='.'){
xx=i,yy=j;
break;
}
for(int blk=1;blk<=60;++blk)
if(!use[b[blk].ch])
if(can_put(xx,yy-b[blk].y,blk)){
use[b[blk].ch]=1;
fill(xx,yy-b[blk].y,blk);
dfs(nw+1);
clear(xx,yy-b[blk].y,blk);
use[b[blk].ch]=0;
}
}
int main(){
b[1]=(block){
2,2,{
{1,1},
{1,0}
},'A',0
};
b[2]=(block){
2,2,{
{1,1},
{0,1}
},'A',0
};
b[3]=(block){
2,2,{
{0,1},
{1,1}
},'A',1
};
b[4]=(block){
2,2,{
{1,0},
{1,1}
},'A',0
};
b[5]=(block){
1,4,{
{1,1,1,1}
},'B',0
};
b[6]=(block){
4,1,{
{1},
{1},
{1},
{1}
},'B',0
};
b[7]=(block){
2,3,{
{1,1,1},
{1,0,0}
},'C',0
};
b[8]=(block){
2,3,{
{1,1,1},
{0,0,1}
},'C',0
};
b[9]=(block){
2,3,{
{1,0,0},
{1,1,1}
},'C',0
};
b[10]=(block){
2,3,{
{0,0,1},
{1,1,1}
},'C',2
};
b[11]=(block){
3,2,{
{1,1},
{1,0},
{1,0}
},'C',0
};
b[12]=(block){
3,2,{
{1,1},
{0,1},
{0,1}
},'C',0
};
b[13]=(block){
3,2,{
{1,0},
{1,0},
{1,1}
},'C',0
};
b[14]=(block){
3,2,{
{0,1},
{0,1},
{1,1}
},'C',1
};
b[15]=(block){
2,2,{
{1,1},
{1,1}
},'D',0
};
b[16]=(block){
3,3,{
{1,0,0},
{1,0,0},
{1,1,1}
},'E',0
};
b[17]=(block){
3,3,{
{1,1,1},
{1,0,0},
{1,0,0}
},'E',0
};
b[18]=(block){
3,3,{
{1,1,1},
{0,0,1},
{0,0,1}
},'E',0
};
b[19]=(block){
3,3,{
{0,0,1},
{0,0,1},
{1,1,1}
},'E',2
};
b[20]=(block){
2,4,{
{1,1,1,1},
{0,1,0,0}
},'F',0
};
b[21]=(block){
2,4,{
{1,1,1,1},
{0,0,1,0}
},'F',0
};
b[22]=(block){
2,4,{
{0,1,0,0},
{1,1,1,1}
},'F',1
};
b[23]=(block){
2,4,{
{0,0,1,0},
{1,1,1,1}
},'F',2
};
b[24]=(block){
4,2,{
{1,0},
{1,1},
{1,0},
{1,0}
},'F',0
};
b[25]=(block){
4,2,{
{1,0},
{1,0},
{1,1},
{1,0}
},'F',0
};
b[26]=(block){
4,2,{
{0,1},
{1,1},
{0,1},
{0,1}
},'F',1
};
b[27]=(block){
4,2,{
{0,1},
{0,1},
{1,1},
{0,1}
},'F',1
};
b[28]=(block){
2,3,{
{1,1,1},
{1,0,1}
},'G',0
};
b[29]=(block){
2,3,{
{1,0,1},
{1,1,1}
},'G',0
};
b[30]=(block){
3,2,{
{1,1},
{1,0},
{1,1}
},'G',0
};
b[31]=(block){
3,2,{
{1,1},
{0,1},
{1,1}
},'G',0
};
b[32]=(block){
2,3,{
{1,1,1},
{1,1,0}
},'H',0
};
b[33]=(block){
2,3,{
{1,1,1},
{0,1,1}
},'H',0
};
b[34]=(block){
2,3,{
{1,1,0},
{1,1,1}
},'H',0
};
b[35]=(block){
2,3,{
{0,1,1},
{1,1,1}
},'H',1
};
b[36]=(block){
3,2,{
{1,1},
{1,1},
{1,0}
},'H',0
};
b[37]=(block){
3,2,{
{1,1},
{1,1},
{0,1}
},'H',0
};
b[38]=(block){
3,2,{
{1,0},
{1,1},
{1,1}
},'H',0
};
b[39]=(block){
3,2,{
{0,1},
{1,1},
{1,1}
},'H',1
};
b[40]=(block){
2,4,{
{1,1,1,0},
{0,0,1,1}
},'I',0
};
b[41]=(block){
2,4,{
{0,0,1,1},
{1,1,1,0}
},'I',2
};
b[42]=(block){
2,4,{
{0,1,1,1},
{1,1,0,0}
},'I',1
};
b[43]=(block){
2,4,{
{1,1,0,0},
{0,1,1,1}
},'I',0
};
b[44]=(block){
4,2,{
{1,0},
{1,0},
{1,1},
{0,1}
},'I',0
};
b[45]=(block){
4,2,{
{0,1},
{0,1},
{1,1},
{1,0}
},'I',1
};
b[46]=(block){
4,2,{
{0,1},
{1,1},
{1,0},
{1,0}
},'I',1
};
b[47]=(block){
4,2,{
{1,0},
{1,1},
{0,1},
{0,1}
},'I',0
};
b[48]=(block){
3,3,{
{0,1,0},
{1,1,1},
{0,1,0}
},'J',1
};
b[49]=(block){
3,3,{
{1,0,0},
{1,1,0},
{0,1,1}
},'K',0
};
b[50]=(block){
3,3,{
{0,1,1},
{1,1,0},
{1,0,0}
},'K',1
};
b[51]=(block){
3,3,{
{1,1,0},
{0,1,1},
{0,0,1}
},'K',0
};
b[52]=(block){
3,3,{
{0,0,1},
{0,1,1},
{1,1,0}
},'K',2
};
b[53]=(block){
2,4,{
{1,1,1,1},
{1,0,0,0}
},'L',0
};
b[54]=(block){
2,4,{
{1,1,1,1},
{0,0,0,1}
},'L',0
};
b[55]=(block){
2,4,{
{1,0,0,0},
{1,1,1,1}
},'L',0
};
b[56]=(block){
2,4,{
{0,0,0,1},
{1,1,1,1}
},'L',3
};
b[57]=(block){
4,2,{
{1,1},
{1,0},
{1,0},
{1,0}
},'L',0
};
b[58]=(block){
4,2,{
{1,0},
{1,0},
{1,0},
{1,1}
},'L',0
};
b[59]=(block){
4,2,{
{1,1},
{0,1},
{0,1},
{0,1}
},'L',0
};
b[60]=(block){
4,2,{
{0,1},
{0,1},
{0,1},
{1,1}
},'L',1
};
for(int i=0;i<10;++i)
for(int j=0;j<=i;++j)
Id[i][j]=++tot;
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int ok=0;
for(int i=0;i<10;++i){
cin>>mp[i];
for(int j=0;j<=i;++j)
if(mp[i][j]!='.'&&!use[mp[i][j]])++ok,use[mp[i][j]]=1;
}
dfs(ok);
cout<<"No solution"<<'\n';
return 0;
}