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 ...
随机推荐
- FEC之我见三
继续上文讲解: 3) 标准的RTP头结构如下所示: 其中第一个字节中的x标志位是否扩展了RTP头,RTP协议允许用户自定义的扩展,扩展的字段紧挨上述RTP固定头.RTP扩展投中承载如下信息: 1).当 ...
- bzoj 1398: 寻找主人 AC自动机+最小表示法
题目大意: 给定两个序列判断是否循环同构,若循环同构则输出最小表示 题解: 因为没有样例输入输出,一开始没看到要求输出最小表示 Wa一大页. 但不得不说bzoj还是挺高效的: 赞一个 XD.jpg 判 ...
- VBA记录当前系统时间并精确到毫秒
想做个功能,点一次按钮,就在A1记录一次当前系统时间,要精确到毫秒的.再点一次按钮就在A2显示,以此类推! 例如:这个功能可以用来做歌词记时间! Sub ttt() ActiveCell.Select ...
- Bootstrap CSS教程
Bootstrap 教程 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加 ...
- findBug 错误修改指南
1. EC_UNRELATED_TYPESBug: Call to equals() comparing different types Pattern id: EC_UNRELATED_TYPE ...
- python-queue知识点
1.dict获取value dict.get(key_name)2.三元运算 res,err=stdout.read(),stderr.read() #三元运算 result=res if res e ...
- mongodb的备份还原
一:备份数据库 G:\Program Files\MongoDB\Server\3.0\bin>mongodump -d mydb -o g:/data/back mongodump -h IP ...
- 什么是消息循环,一个简单的win32程序如何运行?
预备知识 1.什么是句柄? (HANDLE) 在win32编程中有各种句柄,那么什么是句柄呢? #define DECLARE_HANDLE(name) struct name##_ { int un ...
- servlet与filter的加载顺序详解
项目:3个filter,3个servlet,匹配的url路径/hello. 情况1:servlet没加<load-on-startup></load-on-startup>情 ...
- C#识别图中二维码
1.在NuGet中添加 ZXing.Net 2.实例代码 /// <summary> /// 识别图中二维码 /// </summary> /// <param name ...