题目大意:给你一个n*m的棋盘 你只能用1x2的格子拼接 且不能同时有4个不同格子的角汇聚在同一处。200组左右的输入 输出任意方案。
题解:由于限制条件太强所以最优方法是确定的 首先假设n
#include
using namespace std;
#define orz printf("orz\n");
#define pf printf
#define ss system("pause");
#define pii pair
#define mp make_pair
#define sz size()
#define pb push_back
#define ft first
#define sd second
int vis[110][110];
int flag,n,m,ff,cnt;
int a[10];
int dx[2][4]={1,0,-1,0,0,1,0,-1};
int dy[2][4]={0,1,0,-1,1,0,-1,0};
int lim1,lim2;
void dfs(int x,int y,int kind,int dir,int f)
{
vis[x][y]=cnt;
int xx;int yy;
for(int i=0;i<4;i++)
{
xx=x+dx[kind][dir];
yy=y+dy[kind][dir];
if(xx<1||xx>n||yylim2||vis[xx][yy])
{
dir=(dir+1)%4;
}
else
{
break;
}
}
if(xx<1||xx>n||yylim2)
{
return;
}
if(vis[xx][yy])
{
return;
}
if(f==1)
{
dfs(xx,yy,kind,dir,f^1);
}
else
{
cnt++;
dfs(xx,yy,kind,dir,f^1);
}
}
int dp[210][2];
vectored[2],st[2];
int labst[10],labed[10];
void solve()
{
memset(dp,-1,sizeof(dp));
dp[0][0]=dp[0][1]=0;
for(int i=0;i<2;i++) ed[i].clear();
for(int i=0;i<2;i++) st[i].clear();
if(n%2==0)
{
ed[0].pb( mp(1 ,1 ) ); labed[1]=0;
ed[0].pb( mp(2 ,n-1) ); labed[2]=0;
ed[0].pb( mp(5 ,n ) ); labed[5]=0;
ed[0].pb( mp(6 ,n+1) ); labed[6]=0;
ed[1].pb( mp(3 ,n-1) ); labed[3]=1;
ed[1].pb( mp(4 ,n ) ); labed[4]=1;
ed[1].pb( mp(7 ,n+1) ); labed[7]=1;
if(n>2)
{
ed[1].pb( mp(8 ,n-2));
labed[8]=1;
st[1].pb( mp(8 ,n-2));
labst[8]=1;
}
st[0].pb( mp(1 ,1 ) ); labst[1]=0;
st[0].pb( mp(3 ,n-1) ); labst[3]=0;
st[0].pb( mp(5 ,n ) ); labst[5]=0;
st[0].pb( mp(7 ,n+1) ); labst[7]=0;
st[1].pb( mp(2 ,n-1) ); labst[2]=1;
st[1].pb( mp(4 ,n ) ); labst[4]=1;
st[1].pb( mp(6 ,n+1) ); labst[6]=1;
}
else
{
ed[1].pb( mp(1 ,n-1) ); labed[1]=1;
ed[1].pb( mp(3 ,n+1) ); labed[3]=1;
ed[0].pb( mp(2 ,n-1) ); labed[2]=0;
ed[0].pb( mp(4 ,n+1) ); labed[4]=0;
st[1].pb( mp(1 ,n-1) ); labst[1]=1;
st[1].pb( mp(3 ,n+1) ); labst[3]=1;
st[0].pb( mp(2 ,n-1) ); labst[2]=0;
st[0].pb( mp(4 ,n+1) ); labst[4]=0;
}
int t1,len;
for(int i=0;im) continue;
t1=st[0][j].ft;
len=st[0][j].sd;
dp[i+len][labed[t1]]=(i<<1)|1;
}
}
if(dp[i][0]!=-1)
{
for(int j=0;jm) continue;
t1=st[1][j].ft;
len=st[1][j].sd;
dp[i+len][labed[t1]]=(i<<1)|0;
}
}
}
}
void path(int y,int kind)
{
//printf("path: %d %d\n",y,kind);
if(y<1) return;
cnt++;
int last=dp[y][kind]>>1;
int situ=dp[y][kind]&1;
lim1=last+1;lim2=y;
dfs(1,last+1,situ^1,0,1);
path(last,situ);
}
void toput()
{
if(ff)
{
//printf("*******************\n");
for(int i=1;i<=m;i++)
{
for(int j=1;jm) swap(n,m),ff=1;
if((n*m) &1)
{
printf("Impossible!\n");
continue;
}
if(n==1)
{
lim1=1;lim2=m;
cnt++;
dfs(1,1,1,0,1);
toput();
continue;
}
solve();
if(dp[m][1]==-1 &&dp[m][0]==-1)
{
printf("Impossible!\n");
}
else print();
}
return 0;
}