其他分享
首页 > 其他分享> > 【BZOJ1142】[POI2009] Tab(这道SB题居然卡常)

【BZOJ1142】[POI2009] Tab(这道SB题居然卡常)

作者:互联网

点此看题面

大致题意: 给定两个\(n\times m\)的矩阵,保证同个矩阵中元素两两不同,问能否交换若干次行和列由第一个矩阵得到第二个矩阵。

前言

\(SB\)题,本来只想水一水,结果被BZOJ卡常了。

好不容易卡过,一怒之下就来水篇博客发泄一下。

以下是我的提交记录:

于是我就被一道水题再次搞得心态爆炸。

题解

显然,无论怎么交换,同一行的数依然同一行,同一列的数依然同一列。

因此只要标记一下哪些数同一行/同一列,就可以了。

代码

#pragma GCC optimize(2)
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000
using namespace std;
int n,m,a[N+5][N+5],P1[N+5],P2[N+5],dc,dv[N*N+5],p1[N*N+5],p2[N*N+5];
class FastIO
{
	private:
		#define FS 100000
		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
		#define tn (x<<3)+(x<<1)
		#define D isdigit(c=tc())
		int f;char c,*A,*B,FI[FS];
	public:
		I FastIO() {A=B=FI;}
		Tp I void read(Ty& x) {x=0,f=1;W(!D) f=c^'-'?1:-1;W(x=tn+(c&15),D);x*=f;}
}F;
int main()
{
	RI Tt,i,j,x,t,f;F.read(Tt);W(Tt--)
	{
		F.read(n),F.read(m),dc=0;
		for(i=1;i<=n;++i) for(j=1;j<=m;++j) F.read(a[i][j]),dv[++dc]=a[i][j];
		sort(dv+1,dv+dc+1),dc=unique(dv+1,dv+dc+1)-dv-1;//离散化
		#define GV(x) lower_bound(dv+1,dv+dc+1,x)-dv
		for(i=1;i<=n;++i) for(j=1;j<=m;++j) a[i][j]=GV(a[i][j]),p1[a[i][j]]=i,p2[a[i][j]]=j;//记录每个数在哪一行/哪一列
		f=1,F.read(t),dv[x=GV(t)]^t&&(f=0),P1[1]=p1[x],P2[1]=p2[x];//记下第二个矩阵中第一行、第一列在第一个矩阵中对应行列
		for(j=2;j<=m;++j) F.read(t),dv[x=GV(t)]^t&&(f=0),p1[x]^P1[1]&&(f=0),P2[j]=p2[x];//记下第二个矩阵中每一列对应列
		for(i=2;i<=n;++i)
		{
			F.read(t),dv[x=GV(t)]^t&&(f=0),P1[i]=p1[x],p2[x]^P2[1]&&(f=0);//记下该行对应行
			for(j=2;j<=m;++j) F.read(t),dv[x=GV(t)]^t&&(f=0),(p1[x]^P1[i]||p2[x]^P2[j])&&(f=0);
		}
		for(i=1;i<=dc;++i) p1[i]=p2[i]=0;puts(f?"TAK":"NIE");
	}return 0;
}

标签:洛谷,WA,同一,矩阵,BZOJ1142,Tab,POI2009,define,BZOJ
来源: https://www.cnblogs.com/chenxiaoran666/p/BZOJ1142.html