Description
输出任意一种即可,题目有SPJ
Solution
可以考虑先枚举终点。
那么一条路径我们可以通过绕圈来修改它
具体而言,从任意一个点,走到一个格子的左上角,绕着这个格子走一圈,再原路返回,这样相当于只将这个格子四个方向的格子取反
对于起点到枚举的终点的路径,随便怎么走,都可以通过上面绕格子的方式修改成所有的路径
那么枚举终点随便走了一条路径后,原问题转化成可以选择一些格子,将这个格子四周取反,求使所有格子变成白色的方案。
显然操作顺序没有影响,考虑按1~N行做
发现当前行的操作状态完全由上一行决定,因为过了这一行再也没有能修改前一行的操作了
那么上一行的状态前移、后移一位异或上当前行就是当前行的状态,同时对下一行也产生影响,下一行也异或上它
那么当做到最后一行全为0时输出,否则当前枚举的终点无解,继续枚举
关键是第一行的状态
可以枚举,但是复杂度比较大
事实上,第一行全部都不用选,因为可以选择其他行的一些格子,最终的状态与选择第一行的格子等价
因为原矩阵是正方形
选红色格子,对蓝色格子取反
可以发现选所有的绿色格子,和选红色的格子的影响是等价的
那么第一行就可以全不选
有道题叫玩诈欺的小杉,和这题转化后非常相似
话说那是我最早写的几篇Blog之一。。。。
http://blog.csdn.net/hzj1054689699/article/details/50571564
Code
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 16
using namespace std;
int b[N],a[N],n,rd[N];
void walk(int x,int y,int p,int q)
{
if(x>p) printf("U"),walk(x-1,y,p,q);
else if(y>q) printf("L"),walk(x,y-1,p,q);
else if(y<q) printf("R"),walk(x,y+1,p,q);
else if(x<p) printf("D"),walk(x+1,y,p,q);
}
void fx(int x,int y)
{
b[x]^=(1<<(y-1));
}
void chd(int x,int y)
{
if(y<=n) fx(x,y);
if(y>1) fx(x,y-1);
}
void chh(int x,int y)
{
if(x<=n) fx(x,y);
if(x>1) fx(x-1,y);
}
void wk(int x,int y,int p,int q)
{
if(x>p) chd(x-1,y),wk(x-1,y,p,q);
else if(y>q) chh(x,y-1),wk(x,y-1,p,q);
else if(y<q) chh(x,y),wk(x,y+1,p,q);
else if(x<p) chd(x,y),wk(x+1,y,p,q);
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
scanf("%d",&n);
if(n==1)
{
int v,p,q;
scanf("%d",&v);
scanf("%d%d",&p,&q);
if(v==0)printf("\n");
else
{
if(p==1) printf("D\n");
else printf("U\n");
}
continue;
}
fo(i,1,n)
{
fo(j,1,n) scanf("%d",&rd[n-j+1]);
fo(j,1,n)
{
b[i]=b[i]*2+rd[j];
a[i]=b[i];
}
}
int x,y,v=(1<<n),bp=0;
scanf("%d%d",&x,&y);
fo(p,1,n+1)
{
fo(q,1,n+1)
{
fo(i,1,n+1) b[i]=a[i];
wk(x,y,p,q);
fo(i,2,n)
{
b[i]=b[i]^(b[i-1]*2%v)^(b[i-1]/2);
b[i+1]=b[i+1]^b[i-1];
}
if(b[n]!=0) continue;
else
{
bp=1;
walk(x,y,p,q);
fo(i,2,n)
{
fo(j,1,n)
{
if(b[i-1]&((1<<(j-1))))
{
walk(p,q,i,j);
printf("RDLU");
walk(i,j,p,q);
}
}
}
printf("\n");
break;
}
if(bp)break;
}
if(bp) break;
}
if(!bp) printf("No Solution!\n");
}
}