AT2166 Rotate 3x3
传送门
这个题网上有两种做法,一种是树状数组的,还有一种是暴力模拟的,暴力模拟显然不够优美,所以我用的树状数组
显然可以从初状态推到目标状态,我们也可以考虑倒推回去
首先可以容易发现每列的数字是不变的,所以可以把一些奇奇怪怪的情况先处理掉
每次旋转会使矩阵翻转并且每列取反,发现行其实没什么用,可以丢掉
然后我们定义一个序列的奇偶性为:反的列的数量的奇偶性
那么我们现在就转化为一个问题:
给你一个长度为\(n\)的序列,每次可以选择连续的\(3\)个数翻转并取反,问能否达到\(1,2,3...n\)的状态
假如不考虑符号,考虑翻转操作其实就是交换同一奇偶性的两个相邻数
然后发现奇数列和偶数列是相对独立的,所以可以把奇数列和偶数列拎出来单独处理
然后就是一个经典问题了:每次交换两个相邻的数,使序列有序最少的交换次数是逆序对个数
所以用树状数组求出逆序对就好了。
然后考虑一下符号,奇数列每次翻转会导致偶序列的一个位置被取反(也就是改变偶数列的奇偶性)
所以求出逆序对数后,就可以算出有序状态下的奇数列和偶数列的奇偶性
然后我们手玩一下可以得知,我们可以任意取反同一奇偶性的相邻两个数而不对其他数造成影响
手玩过程如下(定义大写字母为反的,小写字母为正的):
&abcde\\
&CBAde\\
&CBEDa\\
&ebcDa\\
&ebAdC\\
&aBEdC\\
&aBcDe----偶数列取反\\
&adCbe\\
&cDAbe\\
&cBade\\
&AbCde----奇数列取反\\
\end{align}
\]
这样我们就只需要奇数列和偶数列的奇偶性都为偶就是可以达到的状态
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
void read(int &x){
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
#define rg register
const int maxn=1e5+10;bool flag;
int n,m,x[maxn*4],y[maxn*4],z[maxn*4],mp[4][maxn];
int f[maxn*4],w[maxn*4],tot,ans,ans1,s[2],ss[2];
#define lowbit(i) (i&(-i))
void add(int x){for(rg int i=x;i<=m;i+=lowbit(i))f[i]++;}
int get(int x){int ans=0;for(rg int i=x;i;i-=lowbit(i))ans+=f[i];return ans;}
int main(){
read(m),n=3;
for(rg int i=1;i<=n;i++)
for(rg int j=1;j<=m;j++)
x[i+3*j-3]=i&1,y[i+3*j-3]=j&1,z[i+3*j-3]=j;
for(rg int i=1;i<=n;i++)for(rg int j=1;j<=m;j++)read(mp[i][j]);
for(rg int i=1;i<=n;i++)
for(rg int j=1;j<=m;j++){
int u=1+z[mp[i][j]]*3-3,v=2+z[mp[i][j]]*3-3,w=3+z[mp[i][j]]*3-3;
bool ok1=0,ok2=0,ok3=0;
if(mp[1][j]==u||mp[2][j]==u||mp[3][j]==u)ok1=1;
if(mp[1][j]==v||mp[2][j]==v||mp[3][j]==v)ok2=1;
if(mp[1][j]==w||mp[2][j]==w||mp[3][j]==w)ok3=1;
if(!(ok1&ok2&ok3))flag=1;
if(((i&1)^x[mp[i][j]])||((j&1)^y[mp[i][j]]))flag=1;
}
if(flag){printf("No\n");return 0;}
for(rg int i=1;i<=m;i+=2)if(mp[1][i]!=1+3*z[mp[1][i]]-3)s[1]^=1;
for(rg int i=2;i<=m;i+=2)if(mp[1][i]!=1+3*z[mp[1][i]]-3)s[0]^=1;
for(rg int i=1;i<=m;i+=2)w[++tot]=z[mp[1][i]];
for(rg int i=1;i<=tot;i++)ans+=i-get(w[i])-1,add(w[i]);
for(rg int i=1;i<=m;i++)f[i]=0;tot=0;
for(rg int i=2;i<=m;i+=2)w[++tot]=z[mp[1][i]];
for(rg int i=1;i<=tot;i++)ans1+=i-get(w[i])-1,add(w[i]);
s[1]^=(ans1&1),s[0]^=(ans&1);
if(s[0]||s[1])printf("No\n");
else puts(s[0]!=s[1]?"No":"Yes");
}
AT2166 Rotate 3x3的更多相关文章
- 2017国家集训队作业[agc006e]Rotate 3x3
2017国家集训队作业[agc006e]Rotate 3x3 题意: 给你一个\(3*N\)的网格,每次操作选择一个\(3*3\)的网格,旋转\(180^\circ\).问可不可以使每个位置\(( ...
- [AGC006E] Rotate 3x3 树状数组+贪心
Description XFZ在北京一环内有一套房. XFZ房子的地砖呈网格状分布,是一个3∗N3∗N的网格.XFZ在买下这套房时,每个地砖上有一个数字,位置为(i,j)(i,j)的地砖上的数 ...
- 【做题】agc006e - Rotate 3x3——分析&思维
原文链接 https://www.cnblogs.com/cly-none/p/9800105.html 题意:给出一个三行\(n\)列的矩阵.问它能否由满足\(a_{ij} = 3(j-1) + i ...
- 【AGC006E】 Rotate 3x3
Description 题目链接 Solution 显然每一列只能一起动,乱动则无解. 对原网格按列黑白染色,显然每一列数只能在相同颜色之间交换,乱动则无解. 之后考虑构造方案. ...
- [agc006E]Rotate 3x3
Description 给你一个3*N的网格,位置为(i,j)的网格上的数为i+3(j-1).每次选一个3*3的网格旋转180度,问最后能否使得网格(i,j)的值为ai,j.(5≤N≤105) 如图: ...
- Agc_006 E Rotate 3x3
题目大意 给定一个$3\times N$的方阵,每个位置的数恰好是每一个$[1,3\times N]$中的数. 初始时,每个位置$[x,y]$填的是$3(y-1)+x,(1\leq x\leq N,1 ...
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- AtCoder Grand Contest 006
AtCoder Grand Contest 006 吐槽 这套题要改个名字,叫神仙结论题大赛 A - Prefix and Suffix 翻译 给定两个串,求满足前缀是\(S\),后缀是\(T\),并 ...
- RE:从零开始的AGC被虐(到)生活(不能自理)
RE:从零开始的AGC被虐(到)生活(不能自理) 「一直注视着你,似近似远,总是触碰不到.」 --来自风平浪静的明天 AtCoder Grand Contest 001 B: Mysterious L ...
随机推荐
- UNITY_MATRIX_IT_MV[Matrix]
http://blog.csdn.net/cubesky/article/details/38682975 前面发了一篇关于unity Matrix的文章. http://blog.csdn.NET/ ...
- saltstack集中化管理平台
1.安装与启动 yum install salt-master -y 安装服务端 chkconfig salt-master on 自启动 service salt-master start 启动 y ...
- idea-spark-sbt 打包jar
1.打开idea下的terminal窗口 2.只打包部分项目 sbt insight-import/clean insight-import/assembly 这表示只打包主目录下的insight- ...
- JVM插庄之一:JVM字节码增强技术介绍及入门示例
字节码增强技术:AOP技术其实就是字节码增强技术,JVM提供的动态代理追根究底也是字节码增强技术. 目的:在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修 ...
- Java常见设计模式之适配器模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能 ...
- play 学习 一 : 构建SBT的play项目
因为帮一个朋友做一个简单的项目,档案管理.同时也为了自己能学习PLay框架,所以记录一下. 项目GitHub地址: https://github.com/liufeiSAP/ArchiveManage ...
- WPF bmp和二进制转换
bmp转二进制: FileStream fs = File.OpenRead(filepath); //filepath文件路径 Byte[] tempBuff = new Byte[fs.Lengt ...
- 在python3.6下 发明一个类似python3.7 dataclass数据类,不用在 __init__中self.xx
虽然我用3.6,但我在2.7转3.6时候,把3.3 3.4 3.5 3.6的变化都看了一次,虽然已经忘了哪些变化.同时也关注3.7 3.8的变化,3.7中就有1个数据类印象深刻,因为之前在定义这种类时 ...
- Mac搭建nginx+rtmp服务器
nginx是非常优秀的开源服务器,用它来做hls或者rtmp流媒体服务器是非常不错的选择,本人在网上整理了安装流程,分享给大家并且作备忘. 一.安装Homebrow 已经安装了brow的可以直接跳过这 ...
- C#设计模式(9)——装饰者模式
一.概念 装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能. 二.模型 三.代码实现 /// <summary> /// 手机抽象类 ...