【解题报告】 洛谷 P3492 [POI2009]TAB-Arrays
【解题报告】 洛谷 P3492 [POI2009]TAB-Arrays
这题是我随机跳题的时候跳到的。写完这道题之后,顺便看了一下题解,发现只有一篇题解,所以就在这里顺便写一个解题报告了。
首先当然是题目链接
顺便贴一下csdn的网址
题目描述
给出两个n*m的矩阵,保证每个矩阵内元素互不相同且权值均在[-106,106]之间,请能否把其中一个矩阵通过若干次交换两行或者交换两列的操作变成另外一个矩阵。
输入输出格式
输入格式
第一行是一个整数T,表示有T组数据。
每一组数据的第一行是两个整数n和m,表示两个矩阵的大小是n行m列。接下来2*n行里面,每一行有m个数,前n行是第一个矩阵,后n行是第二个矩阵。话说有一点很奇怪,不知道为什么,题目没有给出数据范围,我还是根据内存空间限制算出我能用多少空间的。
输出格式
对于每一组数据,输出一行。若两个矩阵能够通过变换得到对方,则输出TAK,否则,输出NIE
输入输出样例
输入
2
4 3
1 2 3
4 5 6
7 8 9
10 11 12
11 10 12
8 7 9
5 4 6
2 1 3
2 2
1 2
3 4
5 6
7 8
输出
TAK
NIE
解题思路
我们先想一下另外一个问题:现在给你两个数组,问你:是否能把其中一个数组通过若干次交换两个元素的位置变成另外一个数组。
这个问题有一个简单粗暴的做法。对两个数组各自排序,看排序之后的两个数组是否完全相等即可。如,数组[1,4,3,5,6,7]和数组[4,3,6,1,7,5],他们排序过后都是同样的数组[1,3,4,5,6,7],所以这两个数组就可以通过若干次交换两个元素变成另外一个数组。(因为排序的过程就是不断地交换两个元素的位置,如果两个数组A,B都可以通过交换两个元素的位置变成同一个数组C(也就是这个排序之后的数组),那么其中一个数组A也必然可以变成排序之后的数组C,然后数组C再变成另外一个数组B)
上面那个方法可行的原因就在于:他们都可以变成一个排好序的数组,只要比较两个排好序的数组是否相等就可以了。而矩阵看起来不能这么干的原因就在于:你好像不能给他排序。
那么,我们回来我们现在这道题。我们通过仔细地思考,不难发现一个有趣的事实:无论是交换两行,还是交换两列,交换前后,本来在同一列的元素依然在同一列,本来在同一行的元素依然在同一行。只不过,经过交换之后,同一行或则同一列的元素的相对位置会改变而已。
所以,我们有这么一个想法:首先,把最小的一个元素放在左上角,然后分别以第一行为关键字和第一列为关键字对它进行排序。然后比较两个排好序之后的矩阵是否相等。
具体做法如下:
具体做法
- 把矩阵中最小的一个数通过变换放到矩阵的最左上角。(对两个矩阵都进行同样的操作,下面也是一样)
- 以矩阵的第一行为关键字,利用变换,使得第一行的数字有序(从大到小,或者从小到大)
- 以矩阵的第一列为关键字,利用变换,使得第一列的数字有序(从大到小,或者从小到大)
- 比较两个矩阵经过上述两个变换之后是否完全相等。
下面就是我的代码。
AC代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2500;
const int INF=100000000;
struct ary
{
int n[N];
bool operator<(const ary &b)const
{
return n[1]<b.n[1];
}
};
ary a[N],b[N],c[N],d[N];
int main()
{
int test_num;
scanf("%d",&test_num);
while(test_num--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i].n[j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&b[i].n[j]);
int x=0,ma=INF;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i].n[j]<ma)
{
x=j;
ma=a[i].n[j];
}
}
}
for(int i=1;i<=n;i++)
{
int temp=a[i].n[1];
a[i].n[1]=a[i].n[x];
a[i].n[x]=temp;
}
sort(a+1,a+1+n);
ma=INF;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(b[i].n[j]<ma)
{
x=j;
ma=b[i].n[j];
}
}
}
for(int i=1;i<=n;i++)
{
int temp=b[i].n[1];
b[i].n[1]=b[i].n[x];
b[i].n[x]=temp;
}
sort(b+1,b+1+n);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
c[i].n[j]=a[j].n[i];
d[i].n[j]=b[j].n[i];
}
}
sort(c+1,c+1+m);
sort(d+1,d+1+m);
int flag=0;
for(int i=1;i<=m;i++)
{
if(flag) break;
for(int j=1;j<=n;j++)
{
if(c[i].n[j]!=d[i].n[j])
{
flag=1;
break;
}
}
}
if(flag)
{
printf("NIE\n");
}
else printf("TAK\n");
}
return 0;
}
【解题报告】 洛谷 P3492 [POI2009]TAB-Arrays的更多相关文章
- 洛谷 P3486 [POI2009]KON-Ticket Inspector
P3486 [POI2009]KON-Ticket Inspector 题目描述 Byteasar works as a ticket inspector in a Byteotian Nationa ...
- 解题笔记-洛谷-P1010 幂次方
0 题面 题目描述 任何一个正整数都可以用2的幂次方表示.例如 137=2^7+2^3+2^0 同时约定方次用括号来表示,即a^b 可表示为a(b). 由此可知,137可表示为: 2(7)+2(3)+ ...
- 解题:洛谷4721 [模板]分治FFT
题面 这是CDQ入门题,不要被题目名骗了,这核心根本不在不在FFT上啊=.= 因为后面的项的计算依赖于前面的项,不能直接FFT.所以用CDQ的思想,算出前面然后考虑给后面的贡献 #include< ...
- 解题:洛谷4314 CPU监控
题面 线段树·二重标记(什么鬼 用(a,b)标记表示先执行+a操作,然后对b取max,维护历史/当前最大值和历史/当前标记.然后我们发现区间加$x$就是$(x,-inf)$,区间赋$x$就是$(-in ...
- 解题:洛谷4178 Tree
题面 重(新)学点分治中...... 普通的点分治一般这几步: 1.找重心 2.从重心开始DFS,得到信息 3.统计经过重心的路径 4.分别分治几棵子树,继续这个过程 然后是常见的(制杖的我的)一些疑 ...
- 解题:洛谷2093 JZPFAR
题面 初见K-D Tree 其实这样的题(欧几里得距离第$x$近点对)不应该用K-D Tree做,因为会被构造数据卡成$O(n^2)$,随机的另说. 但是并没有找到合适的K-D Tree的题(区域统计 ...
- 解题:洛谷 p1858 多人背包
题面 设$dp[i][j]$表示容量为$i$时的第$j$优解,因为是优解,肯定$dp[i][j]$是随着$j$增大不断递减的,这样的话对于一个新加进来的物品,它只可能从两个容量的转移的前$k$优解中转 ...
- 解题:洛谷2633 Count on a tree
题面 在树上建主席树...... 每个点从父亲那里建过来,最后建出来就是从根到$i$这条链上的主席树,查询的时候一边差分一边查询 ($cmt[u]+cmt[v]-cmt[lca(u,v)]-cmt[a ...
- 解题:洛谷2257 YY的GCD
题面 初见莫比乌斯反演 有一个套路是关于GCD的反演经常设$f(d)=\sum_{gcd(i,j)==d},g(d)=\sum_{d|gcd(i,j)}$,然后推推推 $\sum\limits_{i= ...
随机推荐
- LeetCode 781. Rabbits in Forest (森林中的兔子)
题目标签:HashMap 题目给了我们一组数字,每一个数字代表着这只兔子说 有多少只一样颜色的兔子. 我们把每一个数字和它出现的次数都存入map.然后遍历map,来判断到底有多少个一样颜色的group ...
- 2015南阳CCPC H - Sudoku 数独
H - Sudoku Description Yi Sima was one of the best counselors of Cao Cao. He likes to play a funny g ...
- 20170620_javaweb_小结
01.session失效的方式 02. session和cookie的区别 03.jsp九大内置对象,意义 以及对应的java类 04.转发和重定向 05.jsp的执行过程 和 生命周期 06.实现s ...
- 深入理解7816(3)-----关于T=0 【转】
本文转载自:http://blog.sina.com.cn/s/blog_4df8400a0102vcyp.html 深入理解7816(3)-----关于T=0 卡片和终端之间的数据传输是通过命令响应 ...
- 乐视云监控数据存放到influxdb中
3.9 监控.告警系统 监控报警我们分PaaS平台和业务应用两大类. PaaS平台主要聚焦在基础设施和LeEngine的各个服务组件的监控报警(比如主机CPU,内存,IO,磁盘空间,LeEng ...
- 65. ExtJs获取文本框中值的几种方式
转自:https://blog.csdn.net/qiu512300471/article/details/17415675/ 1.Html文本框 如:<input type=" ...
- java replaceAll 忽略大小写
public static void main(String[] args) { String temp=" CLASS_path : /aaabb/"; System.out.p ...
- es6 import 与 export
1.export 命令 export 命令用于规定模块的对外接口. 一个模块就是一个独立的文件.该文件内部所有的变量,外部无法获取.要想外部能够读取模块内部的某个变量,就必须使用 export 关键字 ...
- [App Store Connect帮助]三、管理 App 和版本(2.4)输入 App 信息:提供加密出口合规证明文稿
上传至 App Store Connect 的 App 被上传至位于美国的 Apple 服务器.如果您提交 App 的目的是为了在 App Store 上分发您的 App 或通过美国或加拿大的境外 T ...
- JS中的this是什么,this的四种用法
在Javascript中,this这个关键字可以说是用的非常多,说他简单呢也很简单,说他难呢也很难,有的人开发两三年了,自己好像也说不清this到底是什么.下面我们来看看: 1.在一般函数方法中使用 ...