【JZOJ 5284】【清华集训2017模拟】超级翻转

来源:互联网 发布:python 微信企业号 编辑:程序博客网 时间:2024/06/06 02:00

Description

这里写图片描述

Solution

先枚举一个终点,跑出起点到终点的任意一条简单路径,
我们发现,只要我们在这条路径上的一个位置绕一个圈,这条路径其实就改变了,
(比如:原来是(2,2)->(2,3),绕一圈是(2,2)->(2,3)->(1,3)->(1,2)->(2,2)->(2,3))
因为经过两次的边就等于没走嘛,所以上面这个例子相当于把原路径的这个位置搞凸起来,
又因为题目只要可行解,而这一肯定会有可行解的,

之后我们一行一行做,这一行全部清空,再往下走,
因为我们不能影响到上面,所以要把第i行清空,就必须在i+1行绕圈子(当然这样也会影响到i+2行),
发现,这样是唯一的,只有第一行是没法确认的,其他都可计算出,
有一种暴力就是枚举第一行选哪些绕圈子,

结论:第一行一定不选,
证明:以最上面那个图为例,
如果我们绕(1,2)这个格子,就相当于绕(2,1),(3,2),(4,3),(3,4),(2,3)这5个格子,这是等价的,
其他情况也差不多,这个例子显然是可以推广的,

所以直接做即可

Code

#include <cstdio>#include <cstdlib>#include <algorithm>#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 min(q,w) ((q)>(w)?(w):(q))#define max(q,w) ((q)<(w)?(w):(q))using namespace std;const int N=20;int read(int &n){    char ch=' ';int q=0,w=1;    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());    if(ch=='-')w=-1,ch=getchar();    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int n,ans,x,y;int a[N],b[N];int er[20];int s[N*N*N*N][2],s0;void GOTO(int x,int y,int I,int J){    fo(i,y,J-1)printf("R");    fo(i,J,y-1)printf("L");    fo(i,x,I-1)printf("D");    fo(i,I,x-1)printf("U");}void GOTOb(int x,int y,int I,int J){    fo(i,x,I-1)printf("D");    fo(i,I,x-1)printf("U");    fo(i,y,J-1)printf("R");    fo(i,J,y-1)printf("L");}int main(){    freopen("turn.in","r",stdin);    freopen("turn.out","w",stdout);    int q,w,_;    er[1]=1;fo(i,2,18)er[i]=er[i-1]<<1;    read(_);    while(_--)    {        read(n);        fo(i,1,n)        {            a[i]=0;            fo(j,1,n)if(read(q))a[i]+=er[j];            b[i]=a[i];        }        read(x),read(y);        bool OK=0;        fo(I,1,n+1)if(!OK)fo(J,1,n+1)if(!OK)        {            fo(i,1,n)a[i]=b[i];            fo(i,y,J-1)a[x-1]=a[x-1]^er[i],a[x]=a[x]^er[i];            fo(i,J,y-1)a[x-1]=a[x-1]^er[i],a[x]=a[x]^er[i];            fo(i,x,I-1)a[i]=a[i]^er[J]^er[J-1];            fo(i,I,x-1)a[i]=a[i]^er[J]^er[J-1];            s0=0;            fo(i,1,n-1)            {                a[i]=a[i]&(er[n+1]-1);                q=a[i];                fo(j,1,n)if(q&er[j])s[++s0][0]=i+1,s[s0][1]=j;                a[i]^=q;                a[i+1]=a[i+1]^(q<<1)^(q>>1);                a[i+2]^=q;            }            a[n]=a[n]&(er[n+1]-1);            if(a[n]==0)            {                OK=1;                s[0][0]=I,s[0][1]=J;            }        }        if(OK)        {            fo(i,1,s0)            {                GOTO(x,y,s[i][0],s[i][1]);                printf("RDLU");                GOTOb(s[i][0],s[i][1],x,y);            }            GOTO(x,y,s[0][0],s[0][1]);            printf("\n");        }else printf("No Solution!\n");    }    return 0;}
阅读全文
0 0