Superdoku 二分图匹配

Superdoku

Alice and Bob are big fans of math. In particular, they are very excited about playing games that are related to numbers. Whenever they see a puzzle like Sudoku, they cannot stop themselves from solving it. The objective of Sudoku is to fill a 9 × 9 9 \times 9 9×9 grid with digits so that each column, each row, and each of the nine ( 3 × 3 ) (3 \times 3) (3×3) subgrids that compose the grid (also called “boxes”, “blocks”, or “regions”) contains all of the digits from 11 to 99. The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a single solution.

After many years of solving Sudoku problems, Alice and Bob are tired of Sudoku. They have been trying to develop a harder variation of Sudoku, which they are calling Superdoku. In Superdoku, the grid is bigger – n × n n \times n n×n instead of just 9 × 9 9 \times 9 9×9. However, the “block” constraints are impossible to formulate when there are no further constraints on nn. Therefore, there are no block constraints in Superdoku. Instead, the goal is simply to make sure that each column and each row in the grid contains all of the integers from 11 to nn. After playing for a while in the standard way (where any of the grid cells may have previously been filled in), they decide that the game is too difficult and they want to simplify it. Therefore, they decide to make the initial grid further constrained. They constrain the board by filling in the first kk rows completely.

Alice and Bob both believe that Superdoku is solvable. However, since nn could be very big, it may still take a long time to figure out a solution. They don’t want to spend too much time on this single game, so they are asking for your help!

Input

The input consists of a single test case. The first line lists two space-separated integers 1 ≤ n ≤ 100 1 \le n \le 100 1n100 and 0 ≤ k ≤ n 0 \le k \le n 0kn, denoting the size of the grid ( n × n ) (n \times n) (n×n) and the number of rows k that are already filled in. Each of the following k lines contains nn space-separated integers, denoting the first kk given rows. Allintegers in these k lines are between 11 and nn.

Output

Output either “yes” or “no” on the first line, indicating if there is a solution. If there is no solution, do not output anything more. If there is a solution, output nn more lines, each containing nn space-separated integers, representing a solution. If there are multiple solutions, output any one of them.

本题答案不唯一,符合要求的答案均正确

样例输入
4 2
1 2 3 4
2 3 4 1
样例输出
yes
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3
样例输入
4 2
1 2 3 4
2 2 2 2
样例输出
no

将n*n的网格填满,每行每列必须出现1-n中的所有数。
这本来是一道搜索题,可n是100,搜索的时间复杂度是O(n!),不敢想象。
很显然,如果输入的k行符合条件,那么必然是有解的,用每行的轮换式去套也是能套出答案的。
如果前看行符合,那么,e[i][j]表示第i列可以填j这个数字,如果第i列填了j这个数字,其余列就不能填j了。
对于k+1之后每一行,可以跑一遍二分图匹配,当然这n-k列都是完美媲美匹配。
时间:搜索只能过一半的点,二分图50ms,差太多了吧。。。

#include<bits/stdc++.h>
using namespace std;
#define Init(arr,val) memset(arr,val,sizeof(arr))
const int inf=0x3f3f3f3f,mod=1e9+7,MAXN=101;
typedef long long ll;
bool r[MAXN][MAXN],l[MAXN][MAXN];//搜索里的判断第i行、列j这个数字有没有出现过,可以用e[][]代替,懒得改了。。
bool e[MAXN][MAXN];//e[i][j]第i列能填j
int pre[MAXN],ans[MAXN][MAXN];//数字j被pre[j] 这列填了。
bool vis[MAXN];
int n,k,x;
bool dfs(int i){
    for(int j=1;j<=n;++j){
        if(!e[i][j]||vis[j])continue;
        vis[j]=1;
        if(!pre[j]||dfs(pre[j])){
            pre[j]=i;
            return 1;
        }
    }
    return 0;
}
void solve(int row){//第row行跑一下匹配
    Init(pre,0);
    for(int i=1;i<=n;++i){
        Init(vis,0);
        dfs(i);
    }
    for(int i=1;i<=n;++i){
        ans[row][pre[i]]=i;
        e[pre[i]][i]=0;
    }
}
int main() {
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
    Init(e,1);
    cin>>n>>k;
    for(int i=1;i<=k;++i){
        for(int j=1;j<=n;++j){
            cin>>x;
            if(r[i][x]||l[j][x]){
                cout<<"no";
                return 0;
            }
            r[i][x]=l[j][x]=1;
            e[j][x]=0;
            ans[i][j]=x;
        }
    }
    cout<<"yes\n";
    for(int i=k+1;i<=n;++i)solve(i);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            cout<<ans[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值