题意

现有n*m的长方形网格,每个格子中写着一个数,并构成了[0,n*m)的排列。每次可以将一行循环平移x格,也可以将一列循环平移x格。给出初始状态,给出一个到达给定状态的方案。n*m<=10000,n,m>=2。


思考

发现存在一种方法,能够使任意三个方格进行顺时针或逆时针改变位置。其中有一个方格的行和列由剩余两个方格决定。

这样一来,我们可以将前n-1行排成有序的,只剩下最后一行是无序的。

通过第一张改变位置的方式,我们也可以将同一行的任意三个方格进行循环平移。这样可以将最后一行的前m-2个排成有序的,剩下的两个不一定有序。

这种方法虽然不能判断出是否能够达到有序状态,但是在随机情况下会以一定概率达到。因此可以重复打乱原始序列,进行多次判断。

总复杂度O(Tnm),T为随机次数。


代码

 #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int maxn=1E2+;
int X[maxn*maxn],Y[maxn*maxn];
int a[maxn][maxn],n,m,wait[maxn];
ull seed=;
inline int R(int l,int r)
{
seed^=seed<<;
seed^=seed>>;
seed^=;
return seed%(r-l+)+l;
}
struct note
{
int opt,x,y;
note(int a=,int b=,int c=)
{
opt=a,x=b,y=c;
}
};
vector<note>ans;
inline void swap(int x1,int y1,int x2,int y2,int x3,int y3)
{
swap(X[a[x1][y1]],X[a[x3][y3]]);
swap(Y[a[x1][y1]],Y[a[x3][y3]]);
swap(X[a[x1][y1]],X[a[x2][y2]]);
swap(Y[a[x1][y1]],Y[a[x2][y2]]);
swap(a[x1][y1],a[x3][y3]);
swap(a[x3][y3],a[x2][y2]);
int len1=y2-y1,len2=x2-x3;
if(len1<)
len1+=m;
if(len2<)
len2+=n;
ans.push_back(note(,x1,len1));
ans.push_back(note(,y2,len2));
ans.push_back(note(,x1,m-len1));
ans.push_back(note(,y2,n-len2));
}
inline void swapRow(int x,int y1,int y2,int y3)
{
swap(x,y1,x,y2,x-,y2);
swap(x,y1,x,y2,x-,y2);
swap(x,y3,x,y2,x-,y2);
}
void out()
{
for(int i=;i<=n;++i,cout<<endl)
for(int j=;j<=m;++j)
{
cout.width();
cout<<a[i][j];
}
}
void work()
{
for(int i=;i<=n-;++i)
{
for(int j=;j<=m;++j)
{
int num=(i-)*m+j-;
if(a[i][j]==num)
continue;
if(i==X[num])
swap(X[num],Y[num],i,j,i+,j);
else if(j==Y[num])
swap(X[num],j==?m:,X[num],Y[num],i,j);
else
{
int x=X[num],y=Y[num];
swap(x,y,x,j,i,j);
swap(x,y,x,j,i,j);
}
}
}
for(int i=;i<=m-;++i)
{
int num=(n-)*m+i-;
if(a[n][i]==num)
continue;
if(Y[num]==i+)
swapRow(n,i,i+,i+);
else
{
int G=Y[num];
swapRow(n,i,i+,G);
swapRow(n,i,i+,G);
}
}
}
void row(int x,int y)
{
ans.push_back(note(,x,y));
for(int i=;i<=m;++i)
wait[i]=a[x][i-y>=?i-y:i-y+m];
for(int i=;i<=m;++i)
a[x][i]=wait[i],Y[wait[i]]=i;
}
void col(int x,int y)
{
ans.push_back(note(,x,y));
for(int i=;i<=n;++i)
wait[i]=a[i-y>=?i-y:i-y+n][x];
for(int i=;i<=n;++i)
a[i][x]=wait[i],X[wait[i]]=i;
}
bool check()
{
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if(a[i][j]!=(i-)*m+j-)
return false;
return true;
}
int main()
{
srand(time());
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
{
cin>>a[i][j];
X[a[i][j]]=i,Y[a[i][j]]=j;
}
int T=;
while(T--)
{
work();
if(check())
break;
int t=;
row(n,);
}
if(!check())
{
cout<<-<<endl;
return ;
}
cout<<ans.size()<<endl;
for(int i=;i<ans.size();++i)
cout<<ans[i].opt<<" "<<ans[i].x<<" "<<ans[i].y<<endl;
return ;
}

NOTE:最好要多随机几行和几列,防止极端数据。

19_07_08校内训练[grid]的更多相关文章

  1. [4.14校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi....        很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...

  2. [2017.4.7校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...

  3. [3.24校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...

  4. 19_04_19校内训练[Game]

    题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...

  5. 19_04_02校内训练[deadline]

    题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...

  6. 平面图转对偶图&19_03_21校内训练 [Everfeel]

    对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...

  7. fzyzojP3979 -- [校内训练20180914]魔法方阵

    原题见CF632F https://blog.csdn.net/Steaunk/article/details/80217764 这个比较神仙了 点边转化, 把max硬生生转化成了路径最大值,再考虑所 ...

  8. fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试

    题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...

  9. fzyzojP3372 -- [校内训练20171124]博弈问题

    对于每个点都要答案 还是异或 trie树合并石锤了 朴素枚举是O(n^2*17)的 怎么办呢? 我们发现合并的时候,一些部分的trie的子树还是不变的 改变的部分也就是合并的复杂度可以接受 鉴于大部分 ...

随机推荐

  1. Python15_包的安装和管理

    pip的安装及简单使用:https://www.cnblogs.com/csucat/p/4897695.html 使用pip手动安装第三方库:https://blog.csdn.net/github ...

  2. python基础[16]——解决django连接mysql数据库报错的问题

    Models.py #创建数据表 from django.db import models from django.utils import timezone from tinymce.models ...

  3. MySQL基础之事务编程学习笔记

    MySQL基础之事务编程学习笔记 在学习<MySQL技术内幕:SQL编程>一书,并做了笔记.本博客内容是自己学了<MySQL技术内幕:SQL编程>事务编程一章之后,根据自己的理 ...

  4. 再见,Python2。你好,Python3

     文章首发自我的公众号,转载请注明出处~ ​ Python2的退场,意味着一个时代的结束 ​ 我们这一代程序员基本都接触过python2,很多人也是从python2时代一路走来的.但是,是时候说再见了 ...

  5. 洛谷$P2598\ [ZJOI2009]$狼和羊的故事 网络流

    正解:网络流 解题报告: 传送门! 昂显然考虑最小割鸭$QwQ$,就考虑说每个土地要么属于羊要么属于狼,然后如果一条边上是栅栏一定是相邻两边所属不同. 所以考虑给所有羊向$S$连$inf$,所有狼向$ ...

  6. 1049 数列的片段和 (20 分)C语言

    给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列 { 0.1, 0.2, 0.3, 0.4 },我们有 (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) ...

  7. Python基础复习函数篇

    目录 1.猴子补丁2. global和nonlocal关键字3.迭代器和生成器4.递归函数5.高阶函数和lamdba函数6.闭包7.装饰器 1.   猴子补丁 猴子补丁主要用于在不修改已有代码情况下修 ...

  8. 现代主流框架路由原理 hash、history的底层原理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. WTM 3.1发布,完美支持.netcore 3.1

    在过去的2019年,承蒙各位的厚爱,WTM从零开始一年的时间在GitHub上收获了将近1600星,nuget上的下载量累计超过10万. WTM所坚持的低码开发,快速实现的理念受到了越来越多.netco ...

  10. notepad++中cmd运行中文乱码?

    notepad++中有中文内容时,cmd运行时中文显示乱码,如何处理? 设置-->首选项-->新建-->选择ANSI编码(注意现在的文件不会被转换,要重新把代码拷入修建的文件中才可以 ...