题目:http://codeforces.com/problemset/problem/778/D
完全没思路……就看了题解。
很好地思路是考虑操作可逆,所以起始状态和最终状态都变到一个中转状态,即都是横着的条,或者都是竖着的条。
比如要做成都是横着的条,考虑从左上到右下依次做好即可。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=55,lm=1e5,M=lm+5; int n,m,tot; bool fg; char a[N][N],b[N][N]; struct Node{ int x,y; Node(int x=0,int y=0):x(x),y(y) {} }s[M],prn[M]; bool chk(int x,int y) { if(a[x][y]=='L'&&a[x+1][y]=='L')return true; if(a[x][y]=='U'&&a[x][y+1]=='U')return true; return false; } void rot(int x,int y) { s[++tot]=Node(x,y); if(a[x][y]=='U') { a[x][y]=a[x+1][y]='L'; a[x][y+1]=a[x+1][y+1]='R'; } else { a[x][y]=a[x][y+1]='U'; a[x+1][y]=a[x+1][y+1]='D'; } } void cz1()//horizenal { for(int i=1;i<=n;i++) for(int j=1;j<=m;j+=2) { if(a[i][j]=='L')continue; int x=i,y=j; while(!chk(x,y)) { if(a[x+1][y+1]=='L') {rot(x,y+1);break;} x++;y++; } while(1) { rot(x,y); if(x==i)break; rot(x-1,y);x--;y--; if(tot>lm){fg=1;return;} } } } void cz2() { for(int i=1;i<=n;i+=2) for(int j=1;j<=m;j++) { if(a[i][j]=='U')continue; int x=i,y=j; while(!chk(x,y)) { if(a[x+1][y+1]=='U') {rot(x+1,y);break;} x++;y++; } while(1) { rot(x,y); if(x==i)break; rot(x,y-1); x--;y--; if(tot>lm){fg=1;return;} } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%s",a[i]+1); for(int i=1;i<=n;i++) scanf("%s",b[i]+1); if((m&1)==0)cz1(); else cz2(); if(fg){puts("-1");return 0;} int ans=tot; tot=0; for(int i=1;i<=ans;i++)prn[i]=s[i]; memcpy(a,b,sizeof b); if((m&1)==0)cz1(); else cz2(); if(fg||ans+tot>lm){puts("-1");return 0;} for(int i=tot;i;i--)prn[++ans]=s[i]; printf("%d ",ans); for(int i=1;i<=ans;i++) printf("%d %d ",prn[i].x,prn[i].y); return 0; }