码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ1142】【POI2009】Tab 乱搞

时间:2015-05-13 10:27:25      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:bzoj1142   poi2009   tab   乱搞   

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/45688219");
}

注:我没用hash。

题解:

首先我们发现无论如何变换,该在一行的还是会在一行,该在一列的还是会在一列。
拿行举例:我们交换行,在一行的一定还同一行,不在一行的一定还不在同一行;我们交换列,则一个元素的行标号不会被改变,行上的【(在/不在)同一行】这条性质一定不会改变。
然后这样我们扫两遍矩阵。
第一遍我们把每行内元素排序,然后再把矩阵的每一行排下序, O(nm) 比较两个矩阵是否完全相同。

然后第二遍则把列内元素排序,再把每一列排序,然后再比较一遍。

这个做法存在一个坑,就是你怎么知道这样就能变换过去?完全是YY的嘛!
呃貌似不是坑。。。。
如果是“TAK”,我们把该在同一行的都搞到对应行(判断过肯定能的),然后这个时候每行的元素集合肯定是相同的。但是行内可能会有问题。
于是我们再暴力对某一行内元素交换位置使得两矩阵此行相同。因为同列的元素集合都一样,所以两矩阵其它的所有行的元素也都对应上了。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
using namespace std;
int n,m,a[N][N],b[N][N];
int s[N],t[N];
struct Eli
{
    int X[N];
    void keep(int n){sort(X+1,X+n+1);}
    bool operator < (const Eli &V)const
    {return X[1]<V.X[1];}
}A[N],B[N];
int main()
{
    int i,j,g;

    for(scanf("%d",&g);g--;)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]);
        for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&b[i][j]);

        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)A[i].X[j]=a[i][j];
            A[i].keep(m);
        }
        sort(A+1,A+n+1);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)B[i].X[j]=b[i][j];
            B[i].keep(m);
        }
        sort(B+1,B+n+1);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)if(A[i].X[j]!=B[i].X[j])break;
            if(j<=m)break;
        }
        if(i<=n){puts("NIE");continue;}
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)A[i].X[j]=a[j][i];
            A[i].keep(n);
        }
        sort(A+1,A+m+1);
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)B[i].X[j]=b[j][i];
            B[i].keep(n);
        }
        sort(B+1,B+m+1);
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)if(A[i].X[j]!=B[i].X[j])break;
            if(j<=n)break;
        }
        if(i<=m){puts("NIE");continue;}

        puts("TAK");
    }
    return 0;
}

【BZOJ1142】【POI2009】Tab 乱搞

标签:bzoj1142   poi2009   tab   乱搞   

原文地址:http://blog.csdn.net/vmurder/article/details/45688219

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!