题意:
给定n*m的地图
问用L型能否覆盖所有 .
且不允许覆盖到*
L型形如:
*
**
可以允许一个L 旋转
思路:
二进制枚举所有状态
因为只有15个.
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
inline int Max(int a,int b){return a>b?a:b;}
inline int Min(int a,int b){return a<b?a:b;}
#define N 250
#define inf 10000000
int n,m;
struct node{
int x, y;
}hehe[20];
int all;
bool map[N][N];
int vis[N][N];
int Stack[20],top;
int abs(int x){return x>0?x:-x;}
bool Inmap(int x,int y){
if(x>=n || x<0 || y>=m || y<0)return false;
return true;
}
bool hao(node a,node b){
int len = abs(a.x-b.x)+abs(a.y-b.y);
if(len>2)return false;
if(a.y==b.y)
{
if(len == 2)return false;
if(!Inmap(a.x, a.y+1) || map[a.x][a.y+1])return true;
if(!Inmap(a.x, a.y-1) || map[a.x][a.y-1])return true;
if(!Inmap(b.x, b.y+1) || map[b.x][b.y+1])return true;
if(!Inmap(b.x, b.y-1) || map[b.x][b.y-1])return true;
return false;
}
if(a.x==b.x)
{
if(len == 2)return false;
if(!Inmap(a.y, a.x+1) || map[a.y][a.x+1])return true;
if(!Inmap(a.y, a.x-1) || map[a.y][a.x-1])return true;
if(!Inmap(b.y, b.x+1) || map[b.y][b.x+1])return true;
if(!Inmap(b.y, b.x-1) || map[b.y][b.x-1])return true;
return false;
}
if(a.x<b.x)
{
if(!Inmap(a.x-1,a.y) || map[a.x-1][a.y]) return true;
if(!Inmap(a.x+1,a.y) || map[a.x+1][a.y]) return true;
return false;
}
else
{
if(!Inmap(a.x, a.y-1) || map[a.x][a.y-1]) return true;
if(!Inmap(a.x, a.y+1) || map[a.x][a.y+1]) return true;
return false;
}
}
bool hao3(node a,node b,node c){
if(a.x == b.x && a.x == c.x)return false;
if(a.y == b.y && a.y == c.y)return false;
int lala[3];
lala[0] = abs(a.x-b.x)+abs(a.y-b.y);
lala[1] = abs(a.x-c.x)+abs(a.y-c.y);
lala[2] = abs(c.x-b.x)+abs(c.y-b.y);
return lala[0]+lala[1]+lala[2] == 4;
}
bool hao1(node e){
if(!Inmap(e.x-1,e.y) || map[e.x-1][e.y])
{
if(!Inmap(e.x,e.y-1) || map[e.x][e.y-1])return true;
if(!Inmap(e.x,e.y+1) || map[e.x][e.y+1])return true;
}
else if(!Inmap(e.x+1,e.y) || map[e.x+1][e.y])
{
if(!Inmap(e.x, e.y+1) || map[e.x][e.y+1])return true;
if(!Inmap(e.x, e.y-1) || map[e.x][e.y-1])return true;
}
return false;
}
int main(){
int i, j;
while(scanf("%d %d",&n,&m), n){
all = 0;
for(i=0;i<n;i++)
{
char s[N];scanf("%s",s);
for(j=0;j<m;j++)
if(s[j] == '#')map[i][j] = false;
else {
map[i][j] = true;
hehe[all].x = i;
hehe[all].y = j;
all++;
}
}
if(all == 0){printf("0\n");continue;}
int maxx = (1<<all)-1, ans = 10000;
for(i=0;i<=maxx;i++)
{
int num = 0;
for(j=0;j<all;j++)vis[ hehe[j].x ][hehe[j].y] = 0;
bool ok = true;
for(j = 0;j<all;j++)
if(i & (1<<j))
{
vis[hehe[j].x][hehe[j].y] = 1;
if(Inmap(hehe[j].x-1, hehe[j].y) && map[hehe[j].x-1][hehe[j].y] == false){ok = false;break;}
vis[hehe[j].x-1][hehe[j].y] = 1;
if(Inmap(hehe[j].x, hehe[j].y+1) && map[hehe[j].x][hehe[j].y+1] == false){ok = false;break;}
vis[hehe[j].x][hehe[j].y+1] = 1;
num++;
}
if(ok == false)continue;
top = 0;
for(j=0;j<all;j++)
if(vis[ hehe[j].x ][hehe[j].y] == 0){ok = false; Stack[top++] = j;}
if(ok){ans = Min(ans, num); continue;}
if(top>3)continue;
if(top==3)
{if(!hao3(hehe[ Stack[0] ], hehe[Stack[1]], hehe[Stack[2]]))continue;}
else if(top == 2)
{if(!hao(hehe[Stack[0]], hehe[Stack[1]]))continue;}
else
{
if(!hao1(hehe[Stack[0]]))continue;
}
ans = Min(ans, num+1);
}
if(ans == 10000)ans = -1;
printf("%d\n",ans);
}
return 0;
}
/*
2 2
##
##
2 3
#..
..#
3 3
###
#.#
###
4 2
#.
..
.#
..
1 1
.
2 1
.
#
1 2
#.
1 5
.#...
1 4
.#..
2 5
...#.
####.
6 4
#.##
..#.
#.#.
#..#
....
....
5 5
#..#.
##.#.
####.
#.###
#..##
2 2
..
#.
2 2
..
..
2 2
##
.#
2 2
##
#.
2 3
###
#..
2 3
#.#
#.#
*/