[CF1500C] Matrix Sorting (模拟)
场上最后十几秒交上去过掉了耶!
题面
这里有两个
N
∗
M
N*M
N∗M 的
E
x
c
e
l
\rm Excel
Excel 表格
A
A
A 和
B
B
B。
我们知道
E
x
c
e
l
\rm Excel
Excel 表格有一种排序功能,就是把每一行按照某一列的元素排序,这一列元素相同的行保持原相对顺序。
问表格
A
A
A 怎样通过上述的排序变化成表格
B
B
B ?
如果这是不可能的,输出 -1,
否则输出
K
K
K 和
K
K
K 个整数
c
1
,
c
2
,
.
.
.
,
c
K
c_1,c_2,...,c_K
c1,c2,...,cK 表示依次用来排序的列的编号。可重复排序某一列。
N
,
M
≤
1500
N,M\leq 1500
N,M≤1500
题解
首先,做
E
x
c
e
l
\rm Excel
Excel 的经验告诉我们,每一列最多操作一次就够了。
然后,我们倒着想,
A
A
A 只要不是一开始就等于
B
B
B,那么它一定会排个序,既然要排个序,那么
B
B
B 就一定有至少一列是有序的。
我们就假定这列有序的为最后操作的一列。如果有两列及以上同时有序,那么无论最后操作的是哪一列都一样。
于是这一列里相同的连续段就隐含着倒数第二个操作列的线索,因为它们的原相对顺序是不变的。(如果没有相同连续段那自然好,我们就把之前确定的操作列模拟一遍,再判断就行)我们不妨假定有
k
k
k 个连续段
q
1
,
q
2
,
.
.
.
,
q
k
q_1,q_2,...,q_k
q1,q2,...,qk(
q
i
=
[
l
i
,
r
i
]
,
l
i
<
r
i
q_i=[l_i,r_i],l_i<r_i
qi=[li,ri],li<ri)。
我们再看有哪些列满足:没有操作过,且分别在
k
k
k 个连续段内都有序。找到这样的一列,如果有多个就任取一个,然后这列就成为了倒数第二操作列。当然,此时在原来
k
k
k 个连续段内可能还有这一操作列上的连续段。如果有,那么我们再次假定有
k
′
k'
k′ 个连续段
q
1
′
,
q
2
′
,
.
.
.
,
q
k
′
′
q'_1,q'_2,...,q'_{k'}
q1′,q2′,...,qk′′,容易发现,
q
1
′
∪
q
2
′
∪
.
.
.
∪
q
k
′
′
q'_1\cup q'_2\cup...\cup q'_{k'}
q1′∪q2′∪...∪qk′′ 刚好是 倒数第一操作列的连续段并集 和 倒数第二操作列的连续段并集 的交集 再除去长度为 1 的单独区间。
类似的求出倒数第三操作列、倒数第四操作列……直到每一列都操作过或者没有连续段时停止。
最后把
A
A
A 按照求出的操作列序列模拟排个序,与
B
B
B 比较就是了。这里并不需要真的每次
O
(
N
M
l
o
g
N
)
\rm O(NMlogN)
O(NMlogN) 排个序,只需要对一个标号数组排序就行了。注意:<algorithm> 内置 sort 并不是稳定的排序。
CODE
#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1505
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
int n,m,i,j,s,o,k;
int a[MAXN][MAXN],b[MAXN][MAXN];
int cc[5005],cnc;
struct it{
int l,r;it(){l=r=0;}
it(int L,int R){l=L;r=R;}
}q[MAXN],q2[MAXN],c[MAXN];
int cnt;
bool f[MAXN];
int NW;
bool cmp(it x,it y) {
if(a[x.l][NW] != a[y.l][NW]) return a[x.l][NW] < a[y.l][NW];
else return x.r < y.r;
}
int main() {
n = read(); m = read();
for(int i = 1;i <= n;i ++) {
c[i] = it(i,i);
for(int j = 1;j <= m;j ++) a[i][j] = read();
}
for(int i = 1;i <= n;i ++) {
for(int j = 1;j <= m;j ++) b[i][j] = read();
}
q[cnt = 1] = it(1,n);
while(cnt && cnc < 5000) {
int cn = 0,ff = 0;
for(int i = 1;i <= m;i ++) {
if(f[i]) continue;
bool flag = 1;
for(int j = 1;j <= cnt;j ++) {
for(int k = q[j].l+1;k <= q[j].r;k ++) {
if(b[k][i] < b[k-1][i]) {flag = 0;break;}
}
if(!flag) break;
}
if(flag) {
cc[++ cnc] = i;
f[i] = 1; ff = 1;
for(int j = 1;j <= cnt;j ++) {
for(int k = q[j].l;k < q[j].r;k ++) {
if(b[k+1][i] == b[k][i]) {
int ll = k;k ++;
while(k < q[j].r && b[k+1][i] == b[k][i]) k ++;
q2[++ cn] = it(ll,k);
}
}
if(!flag) break;
}
break;
}
}
for(int i = 1;i <= cn;i ++) q[i] = q2[i]; cnt = cn;
}
for(int i = cnc;i > 0;i --) {
NW = cc[i];
sort(c + 1,c + 1 + n,cmp);
for(int j = 1;j <= n;j ++) c[j].r = j;
}
bool flag = 1;
for(int i = 1;i <= n;i ++) {
for(int j = 1;j <= m;j ++) {
if(a[c[i].l][j] != b[i][j]) flag = 0;
}
}
if(flag) {
printf("%d\n",cnc);
for(int i = cnc;i > 0;i --) printf("%d ",cc[i]);ENDL;
}
else printf("-1\n");
return 0;
}
[CF1500C] Matrix Sorting (模拟)的更多相关文章
- URAL(timus) 1280 Topological Sorting(模拟)
Topological Sorting Time limit: 1.0 secondMemory limit: 64 MB Michael wants to win the world champio ...
- BNUOJ-29357 Bread Sorting 模拟
题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=29357 直接模拟就可以了.. //STATUS:C++_AC_190MS_1884KB # ...
- HDU 5122 K.Bro Sorting(模拟——思维题详解)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5122 Problem Description Matt's friend K.Bro is an A ...
- codeforces 400 C Inna and Huge Candy Matrix【模拟】
题意:给出一个矩形的三种操作,顺时针旋转,逆时针旋转,对称,给出原始坐标,再给出操作数,问最后得到的坐标 画一下模拟一下操作就可以找到规律了 #include<iostream> #inc ...
- HDU 6215 Brute Force Sorting 模拟双端链表
一层一层删 链表模拟 最开始写的是一个一个删的 WA #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) mem ...
- Codeforces Round #540 (Div. 3) C. Palindromic Matrix (大模拟)
题意:给你\(n\)个数,判断是否能构成一个\(n\)X\(n\)的回文矩阵,若可以,输出\(YES\)和矩阵,否则输出\(NO\). 题解:如果这个矩阵的行/列元素是偶数的话,很好办,所有出现的数一 ...
- 贪心/构造/DP 杂题选做Ⅱ
由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...
- CG&CAD resource
Computational Geometry The Geometry Center (UIUC) Computational Geometry Pages (UIUC) Geometry in Ac ...
- HDU 6215 Brute Force Sorting(模拟链表 思维)
Brute Force Sorting Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
随机推荐
- Groovy基础语法
Groovy 基础语法 变量定义 1.支持动态类型,使用def关键字定义变量 // Java中定义变量的方式 int age = 18; String name = "张三"; / ...
- 为什么 SQL 语句使用了索引,但却还是慢查询?
一.索引与慢查询 聊一聊索引和慢查询,经常遇到的一个问题:一个SQL语句使用了索引,为什么还是会记录到慢查询日志之中? 为了说明,创建一个表t,该表3个字段,一个主键索引,一个普通索引 CREATE ...
- 互联网大厂目标管理OKR实践落地与反思
上一篇「 互联网公司目标管理OKR和绩效考核的误区 」介绍了使用 OKR 时要澄清的一些概念,但是实际使用中又如何呢?我们快手也是很大的互联网公司,大家都是年轻人,思维活跃,容易接受新事物,敢尝试,但 ...
- python:selenium测试登录在chrome中闪退
问题描述:使用selenium.webdriver时测试网页,进行自动登录测试总是在登录成功时闪退.使用指定驱动器位置的方式chrome也会闪退 1.正常使用chrome驱动打开一个网页,正常访问 f ...
- php个性代码注释
// _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = /O // ____/`---'\____ // . ' \ ...
- 送分题,ArrayList 的扩容机制了解吗?
1. ArrayList 了解过吗?它是啥?有啥用? 众所周知,Java 集合框架拥有两大接口 Collection 和 Map,其中,Collection 麾下三生子 List.Set 和 Queu ...
- Windows-matlab简易安装-用于数字图像处理
安装 下载链接 解压文件得到 双击setup.exe 主要注意几点 使用文件安装密匙 只需安装这三个即可 将两个文件夹里面的dll文件复制到安装目录的 /bin/win64 目录 两个 .lic 文件 ...
- MySQL-2-DQL
DQL:数据查询语言 SQLyog中格式化某段语句片段:CTRL+F12 基础查询 语法: select 查询列表 from 表名: 特点: ① 查询列表可以是:表中的字段.常量值.表达式.函数 ② ...
- Sentinel-流量防卫兵
1.背景 1.1 简介 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. Sentinel 具有以下特征 丰富的应用场景:Sentinel 承接了阿里巴 ...
- Linux操作系统(2):组管理和权限管理
组管理和权限管理 Outline 1.查看文件所有者:ls -ahl 2.更改文件或目录权限命令:chmod 3.更改文件或目录所有者命令:chown 4.更改文件或目录所属组命令:chgrp 1)组 ...