【JZOJ 5284】 超级翻转
2017-08-16 22:29
197 查看
Description
1<=n<=15,1<=数据组数<=5
Analysis
这种题,发现数据范围暴力过不了,就应该发掘一下移动的性质显然一条边走的次数可以简化成0/1
一个格子的状态取决于其相邻四条边走的次数异或
这样可以对每个格子列出方程,不过并不知道这个idea可不可做
继续发掘
如果一个点四周被绕了一圈,那么造成的影响仅是这个格子四周的格子反色
并且,由于我们可以从起点走到一个点绕一圈再原路反回来,所以走原路返回的时候经过的那些边相当于不计影响
这就是个很好的性质了,不论起点在哪,我们都可以任意选定格子,造成的贡献是四周的格子反色
这就有点像这题了
不过也可能不绕圈啊!!!
这TM就GG没关系,我们枚举一个终点
那么起点到终点必定会有一条路径,这条路径是什么?
在路径上绕一个圈试试?
路径刚好进行了偏移,归纳一发,我们可以通过选择点绕圈来更改路径(感性)
那么暴力走一遍,暴力反色,就变成上面那个题了
然后应该就能过了,复杂度应该是n32n,实际跑得挺快
你以为这样就完了?
一个巨大的优化
选红勾的格子等价于选蓝勾的格子
我们不需要枚举第一行的状态
存在一种可行解,第一行全不选
复杂度变成n3
Code
#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,b,a) for(int i=b;i>=a;i--) #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) #define mset(a,x) memset(a,x,sizeof(a)) using namespace std; typedef long long ll; const int N=20; int n,xs,ys,xt,yt,a ,b ,c ; //c:a matrix,value 1/0 standing node(i,j) is choosen or not void go(int xs,int ys,int xt,int yt) { int fx=xs<xt?1:-1; for(;xs!=xt;xs+=fx) if(fx==1) b[xs][ys-1]^=1,b[xs][ys]^=1; else b[xs-1][ys-1]^=1,b[xs-1][ys]^=1; fx=ys<yt?1:-1; for(;ys!=yt;ys+=fx) if(fx==1) b[xs-1][ys]^=1,b[xs][ys]^=1; else b[xs-1][ys-1]^=1,b[xs][ys-1]^=1; fo(i,0,n+1) b[i][0]=b[0][i]=b[i][n+1]=b[n+1][i]=0; } void output(int xs,int ys,int xt,int yt,int p) { int fx; if(!p) { fx=xs<xt?1:-1; for(;xs!=xt;xs+=fx) putchar(fx==1?'D':'U'); fx=ys<yt?1:-1; for(;ys!=yt;ys+=fx) putchar(fx==1?'R':'L'); } else { fx=ys<yt?1:-1; for(;ys!=yt;ys+=fx) putchar(fx==1?'R':'L'); fx=xs<xt?1:-1; for(;xs!=xt;xs+=fx) putchar(fx==1?'D':'U'); } } int main() { freopen("turn.in","r",stdin); freopen("turn.out","w",stdout); int T; for(scanf("%d",&T);T;T--) { scanf("%d",&n); fo(i,1,n) fo(j,1,n) scanf("%d",&a[i][j]); scanf("%d %d",&xs,&ys); bool p=0; for(xt=1;xt<=n+1;xt++) { for(yt=1;yt<=n+1;yt++) { memcpy(b,a,sizeof(a)); go(xs,ys,xt,yt); mset(c,0); fo(i,2,n)//it can be proved that the first line of c can be all 0 fo(j,1,n) c[i][j]=c[i-1][j-1]^c[i-2][j]^c[i-1][j+1]^b[i-1][j]; bool ok=1; fo(i,1,n) if(c [i-1]^c[n-1][i]^c [i+1]^b [i]) {ok=0;break;} if(!ok) continue; p=1;break; } if(p) break; } if(!p) {puts("No Solution!");continue;} fo(i,1,n) fo(j,1,n) if(c[i][j]) { output(xs,ys,i,j,0); printf("RDLU"); output(i,j,xs,ys,1); } output(xs,ys,xt,yt,0);printf("\n"); } return 0; }
相关文章推荐
- [JZOJ5284] 超级翻转
- 【JZOJ 5284】【清华集训2017模拟】超级翻转
- 【JZOJ5284】 超级翻转
- JZOJ 1331——超级教主【dp】
- JZOJ 1331. 超级教主
- 【欧拉回路+高斯消元】超级翻转
- jzoj P1331 超级教主___dp+单调队列
- 超级恶心的MSN
- nyoj 76 超级台阶
- 单链表翻转Java实现
- JZOJ5399. 【NOIP2017提高A组模拟10.7】Confess bitset
- FTP站点超级连接视图与文件夹视图的切换
- Android开发教程:文字翻转动画的实现
- [OICamp 2016 Day 5/JZOJ4779]鞍点
- 第四章 “字符串和多维数组”翻转学习任务
- 今天下午干掉一个超级bug
- 翻转单词顺序
- 【JZOJ 4787】数格子
- Jzoj4626 矩阵
- CSS的超级技巧大放送1