19_07_08校内训练[grid]
题意
现有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]的更多相关文章
- [4.14校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi.... 很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...
- [2017.4.7校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...
- [3.24校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...
- 19_04_19校内训练[Game]
题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...
- 19_04_02校内训练[deadline]
题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...
- 平面图转对偶图&19_03_21校内训练 [Everfeel]
对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...
- fzyzojP3979 -- [校内训练20180914]魔法方阵
原题见CF632F https://blog.csdn.net/Steaunk/article/details/80217764 这个比较神仙了 点边转化, 把max硬生生转化成了路径最大值,再考虑所 ...
- fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试
题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...
- fzyzojP3372 -- [校内训练20171124]博弈问题
对于每个点都要答案 还是异或 trie树合并石锤了 朴素枚举是O(n^2*17)的 怎么办呢? 我们发现合并的时候,一些部分的trie的子树还是不变的 改变的部分也就是合并的复杂度可以接受 鉴于大部分 ...
随机推荐
- web.config修改文件修改上传大小
老是要修改上传文件大小的限制,先记在这里. <httpRuntime maxRequestLength= "1048576 " //最大长度 executionTimeout ...
- 1.1 Lack of free swap space on zabbix_server (zabbix监控报错)
1.首先看一下内存 free -m 2.然后创建一个分区添加交换文件 mkdir /home/temp dd if=/dev/zero of=/home/temp/swap bs=1024 count ...
- 从零开始のcocos2dx生活(五)ActionEase
文章目录 sineEaseIn sineEaseOut sineEaseInOut expoEaseIn expoEaseOut expoEaseInOut easeIn easeOut easeIn ...
- 【题解】HDU Homework(倍增)
[题解]HDU Homework(倍增) 矩阵题一定要多多检查一下是否行列反了... 一百个递推项一定要存101个 说多了都是泪啊 一下午就做了这一道题因为实在是太菜了太久没写这种矩阵的题目... 设 ...
- Jenkins构建Vue项目
一.Jenkins Job相关配置 二.发布脚本 [root@pdata-nps05 nps]# cat nps_web-page.sh #!/bin/sh USER_IP=172.168.168.1 ...
- Cassandra数据建模中最重要的事情:主键
Cassandra数据建模中要了解的最重要的事情:主键 使用关系数据建模,您可以从主键开始,但是RDBMS中的有效数据模型更多地是关于表之间的外键关系和关系约束.由于Cassandra无法使用JOIN ...
- C++string中find,find_first_of和find_last_of的用法
1. size_t find (const string& str, size_t pos = 0) str.find(str1) 说明:从pos(默认是是0,即从头开始查找)开始查找,找到第 ...
- 原生javascript实现仿QQ延时菜单
一.实现原理 定时器和排他思想 二.代码 <!DOCTYPE html> <html> <head> <title></title> < ...
- Inception V1、V2、V3和V4
Inception模块分为V1.V2.V3和V4. V1(GoogLeNet)的介绍 论文:Going deeper with convolutions 论文链接:https://arxiv.org/ ...
- Scala实践6
1 if表达式 Scala中if...else..表达式是有返回值的,如果if和else返回值类型不一样,则返回Any类型. scala> val a3=10 a3: Int = 10 sca ...