zoukankan      html  css  js  c++  java
  • UVA11625_Lines of Containers

    题意很简单,给你一个n*m的矩阵,现在问你这个矩阵能否变为标准矩阵(即数字从小到大),如果能最少需要几步呢?

    其实是个赤果果的水题。记得暑假安叔也出过一个类似的题目,那个好像是在codeforces上面吧。

    以前我不太理解为什么是这样子做的,现在完全理解了。

    对于给定的矩阵,我们可以先不顾其他的,先把任意一列和任意一行放在规定的位置,然后对其他的数进行判断,如果存在不在规定位置的数字,那么这个矩阵就是不合法的;否则这个举证就是合法的。

    为什么这么做是对的呢?? 其实我们可以这样来理解。假设当前我们已经任意放好了一列和一行,但是还有其他的位置的数字不能对应相等,那么为了使另外的位置的数字对应相等,我们必须另外交换某一些列或者某一些行,而这些位置是我们本来就已经排列还的,那么我们本来排列好的位置又错位了,等于是拆东墙补西墙,所以就不可能把正确的矩阵排列出来。其实简而言之也就是行列的交换顺序在二维的情况下是可逆等价的(好像这样说不太合适,但是我也不知道怎么说明白)。正是由于这个性质,我们根据贪心的交换法则得到的解就一定是最优解了。

    好好理解吧就是这样,水题,我就不多说了,直接排列好第一行和第一列,后面直接验证就好了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define maxn 330
    using namespace std;
    
    int a[maxn][maxn],n,m,k,ans,x1,y1;
    
    void swapl(int y1,int y2)
    {
        for (int i=1; i<=n; i++) swap(a[i][y1],a[i][y2]);
    }
    
    void swapc(int x1,int x2)
    {
        for (int i=1; i<=m; i++) swap(a[x1][i],a[x2][i]);
    }
    
    bool match()
    {
        x1=y1=ans=0;
        for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++) if (a[i][j]==1) { x1=i,y1=j; break; }
        if (x1==0 || y1==0) return false;
        if (x1!=1) swapc(x1,1),ans++;
        if (y1!=1) swapl(y1,1),ans++;
        for (int i=2; i<=m; i++)
        {
            k=0;
            for (int j=i; j<=m; j++) if (a[1][j]==i) { k=j;break; }
            if (k==0) return false;
            if (k!=i) swapl(k,i),ans++;
        }
        for (int i=1; i<=n; i++)
        {
            k=0;
            for (int j=i; j<=n; j++) if (a[j][1]==i*m-m+1) { k=j;break; }
            if (k==0) return false;
            if (k!=i) swapc(k,i),ans++;
        }
        k=1;
        for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++)
                if (a[i][j]!=k++) return false;
        return true;
    }
    
    int main()
    {
        while (scanf("%d%d",&n,&m)!=EOF)
        {
            for (int i=1; i<=n; i++)
                for (int j=1; j<=m; j++) scanf("%d",&a[i][j]);
            if (match()) printf("%d
    ",ans);
                else printf("*
    ");
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    【Elasticsearch 技术分享】—— ES 常用名词及结构
    【Elasticsearch 技术分享】—— Elasticsearch ?倒排索引?这都是什么?
    除了读写锁,JUC 下面还有个 StampedLock!还不过来了解一下么?
    小伙伴想写个 IDEA 插件么?这些 API 了解一下!
    部署Microsoft.ReportViewe
    关于TFS强制undo他人check out
    几段查看数据库表占用硬盘空间的tsql
    How to perform validation on sumbit only
    TFS 2012 Disable Multiple Check-out
    在Chrome Console中加载jQuery
  • 原文地址:https://www.cnblogs.com/lochan/p/3426090.html
Copyright © 2011-2022 走看看