[JZOJ5284] 超级翻转
来源:互联网 发布:身份证复制软件打不开 编辑:程序博客网 时间:2024/06/07 15:09
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 16using 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"); }}
阅读全文
0 0
- [JZOJ5284] 超级翻转
- 【JZOJ5284】 超级翻转
- 【JZOJ 5284】 超级翻转
- 【欧拉回路+高斯消元】超级翻转
- 【JZOJ 5284】【清华集训2017模拟】超级翻转
- 翻转
- 翻转
- 翻转
- 图片像素翻转。水平翻转,垂直翻转。
- 【C】矩阵翻转(上下翻转、左右翻转)
- 翻转字符串
- 数组翻转
- 单词翻转
- reverse()翻转
- 翻转字符串
- 字符串翻转
- 单链表翻转
- 字符串翻转
- 树上的颜色
- JavaScript、Ajax与jQuery的关系
- Nginx主配置参数详解,Nginx配置网站
- Elasticsearch实现原理分析-3
- Add More Zero个人解题心得
- [JZOJ5284] 超级翻转
- 剑指offer 练习六(Java版)
- linux主机名变成了bogon
- 网易编程题 交错01串
- Navicat远程连接到云服务器中的MySQL
- 随便写写
- mybatis-generator扩展-自定义代码注释
- VIM命令备忘录
- c++利用STL编写简易通讯录