zoukankan      html  css  js  c++  java
  • UOJ #41【清华集训2014】矩阵变换

    Description

    给出一个 $N$ 行 $M$ 列的矩阵$A$, 保证满足以下性质:

    • $M > N$。
    • 矩阵中每个数都是 $[0,N]$ 中的自然数。
    • 每行中, $[1,N]$ 中每个自然数都恰好出现一次。这意味着每行中 $0$ 恰好出现 $M-N$ 次。
    • 每列中,$[1,N]$ 中每个自然数至多出现一次。

    现在我们要在每行中选取一个非零数,并把这个数之后的数赋值为这个数。我们希望保持上面的性质4,即每列中,$[1,N]$ 中每个自然数仍然至多出现一次。

    Solution

    发现对于题目要求对于每一行都匹配一个数

    对于每一行,希望匹配到的数在行内的位置尽量靠前

    对于每一个数,希望在匹配到的行中位置尽量靠后

    可以用延迟接受算法

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    int T,n,m,ma[205][405],pos[205][205],mx[205],my[205];
    queue<int>q;
    inline int read(){
        int w=0,f=1;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return w*f;
    }
    bool GS(){
        memset(mx,0,sizeof(mx)),memset(my,0,sizeof(my));
        for(int i=1;i<=n;i++)q.push(i);
        while(q.size()){
            int u=q.front();
            q.pop();
            for(int i=1;i<=m;i++){
                int x=ma[u][i];
                if(!x)continue;
                if(!my[x]||my[x]&&pos[x][u]>pos[x][my[x]]){
                    if(my[x])q.push(my[x]),mx[my[x]]=0;
                    mx[u]=x,my[x]=u;
                    break;
                }
            }
        }
        for(int i=1;i<=n;i++)if(!mx[i])return false;
        return true;
    }
    int main(){
        T=read();
        for(;T;T--){
            n=read(),m=read();
            for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
                ma[i][j]=read();
                if(ma[i][j])pos[ma[i][j]][i]=j;
            }
            if(GS()){
                for(int i=1;i<=n;i++)printf("%d ",mx[i]);
                putchar(10);
            }
            else puts("\(^o^)/");
        }
        return 0;
    }
    【清华集训2014】矩阵变换
  • 相关阅读:
    力扣238.除自身以外数组的乘积 & 剑指offer 51.构建乘积数组
    网易的Airtest
    ZOOKEEPER
    Apache和Nginx负载均衡集群及测试分析
    mysql——创建索引、修改索引、删除索引的命令语句
    sql-索引的作用
    ADB连接手机的两种方式(usb数据线连接和wifi连接)
    adb shell dumpsys 命令
    count(*) 和 count(1)和count(列名)区别
    博客园页面设置
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14295790.html
Copyright © 2011-2022 走看看