场上最后十几秒交上去过掉了耶!

题面

这里有两个

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 (模拟)的更多相关文章

  1. URAL(timus) 1280 Topological Sorting(模拟)

    Topological Sorting Time limit: 1.0 secondMemory limit: 64 MB Michael wants to win the world champio ...

  2. BNUOJ-29357 Bread Sorting 模拟

    题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=29357 直接模拟就可以了.. //STATUS:C++_AC_190MS_1884KB # ...

  3. HDU 5122 K.Bro Sorting(模拟——思维题详解)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5122 Problem Description Matt's friend K.Bro is an A ...

  4. codeforces 400 C Inna and Huge Candy Matrix【模拟】

    题意:给出一个矩形的三种操作,顺时针旋转,逆时针旋转,对称,给出原始坐标,再给出操作数,问最后得到的坐标 画一下模拟一下操作就可以找到规律了 #include<iostream> #inc ...

  5. HDU 6215 Brute Force Sorting 模拟双端链表

    一层一层删 链表模拟 最开始写的是一个一个删的 WA #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) mem ...

  6. Codeforces Round #540 (Div. 3) C. Palindromic Matrix (大模拟)

    题意:给你\(n\)个数,判断是否能构成一个\(n\)X\(n\)的回文矩阵,若可以,输出\(YES\)和矩阵,否则输出\(NO\). 题解:如果这个矩阵的行/列元素是偶数的话,很好办,所有出现的数一 ...

  7. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  8. CG&CAD resource

    Computational Geometry The Geometry Center (UIUC) Computational Geometry Pages (UIUC) Geometry in Ac ...

  9. HDU 6215 Brute Force Sorting(模拟链表 思维)

    Brute Force Sorting Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

随机推荐

  1. .NET中如何在同步代码块中调用异步方法

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 在同步代码块中调用异步方法,方法有很多. 一.对于有返回值的Task 在同步代码块中直接访问 Task 的 Result ...

  2. iNeuOS工业互联网操作系统,增加搜索应用、多数据源绑定、视图背景设置颜色、多级别文件夹、组合及拆分图元

    目       录 1.      概述... 2 2.      搜索应用... 2 3.      多数据源绑定... 3 4.      视图背景设置颜色... 4 5.      多级别文件夹 ...

  3. javascript写淡入淡出效果的轮播图

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

  4. Leetcode----<Diving Board LCCI>

    题解如下: public class DivingBoardLCCI { /** * 暴力解法,遍历每一种可能性 时间复杂度:O(2*N) * @param shorter * @param long ...

  5. bat-命令行安装软件

    批处理 执行的两种方式 1.直接右键以管理员身份运行 2.在管理员身份的cmd窗口中 .\xxx.bat 执行 区别 第一种方式 当前cmd默认路径为 C:\windows\system32 第二种方 ...

  6. EasyExcel导出添加批注

    直接看代码.根据个人需要做改动 注:POI也可以做批注,文章链接https://www.cnblogs.com/qq1445496485/p/15622664.html /** * 导出(批注) * ...

  7. 如何查看/修改Redis密码

    一.修改密码: 打开redis.windows.conf文件,默认是没有红框框里这句话的,因为默认密码是"",就是没有,跟MySql一样. 加上这句话意思就是密码修改为 root ...

  8. 【机器学习】K-means聚类分析

    前言 聚类问题是无监督学习的问题,算法思想就是物以类聚,人以群分,聚类算法感知样本间的相似度,进行类别归纳,对新输入进行输出预测,输出变量取有限个离散值.本次我们使用两种方法对鸢尾花数据进行聚类. 无 ...

  9. 面向个性化需求的在线云数据库混合调优系统 | SIGMOD 2022入选论文解读

    SIGMOD 数据管理国际会议是数据库领域具有最高学术地位的国际性会议,位列数据库方向顶级会议之首.近日,腾讯云数据库团队的最新研究成果入选 SIGMOD 2022 Research Full Pap ...

  10. 《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(2)-初识Fiddler让你理性认识一下

    1.前言 今天的理性认识主要就是讲解和分享Fiddler的一些理论基础知识.其实这部分也没有什么,主要是给小伙伴或者童鞋们讲一些实际工作中的场景,然后隆重推出我们的猪脚(主角)-Fiddler. 1. ...