• Kattis


    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 grid with digits so that each column, each row, and each of the nine subgrids that compose the grid (also called “boxes”, “blocks”, or “regions”) contains all of the digits from 1 to 9

    . 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

    instead of just 9×9. However, the “block” constraints are impossible to formulate when there are no further constraints on n. 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 1 to n. 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 k

    rows completely.

    Alice and Bob both believe that Superdoku is solvable. However, since n

    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 1n100

    and 0kn, denoting the size of the grid (n×n) and the number of rows k that are already filled in. Each of the following k lines contains n space-separated integers, denoting the first k given rows. All integers in these k lines are between 1 and n

    .

    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 n

    more lines, each containing n

    space-separated integers, representing a solution. If there are multiple solutions, output any one of them.

    Sample Input 1Sample Output 1
    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 
    
    Sample Input 2Sample Output 2
    4 2
    1 2 3 4
    2 2 2 2
    
    no
    

     

    题目大意:

      一个n*n的图给你前k行卫问是否可以补充完整使每一行每一列都是1-n n个数字;

    题解思路:

      对于一个矩阵来说如果题目给的前k行是合法的,那么一定有可行的解是整个矩阵合法;

      所以我们只要保证填入的每一行都是合法的那么到最后的矩阵一定是合法的;

      二分图匹配每点,保证每一行对之前的矩阵来说是合法即可;

      如果填入x本行之前出现过,对之前的x所在的位置行进调整

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    const int maxn=105;
    
    
    int nmap[maxn][maxn],visc[maxn][maxn],visr[maxn][maxn],pos[maxn][maxn],vis[105];
    
    
    int n,k;
    
    
    int dfs(int x,int y)//二分图匹配每一行
    {
        for(int i=1;i<=n;i++)
        {
            if(!visc[y][i]&&!vis[i])//如果当前列没有出现过且没有标记
            {
                vis[i]=1;//标记
                if(!visr[x][i]||dfs(x,pos[x][i]))//如果当前行未出现过 或可以进行前面的调整使其合法
                {
                    nmap[x][y]=i;//
                    pos[x][i]=y;//记录出现的位置
                    visr[x][i]=1;//行的标记
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=k;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&nmap[i][j]);
                if(visr[i][nmap[i][j]]||visc[j][nmap[i][j]])
                    goto f;
                visr[i][nmap[i][j]]=1;
                visc[j][nmap[i][j]]=1;
            }//判断图是否合法
    
        //cout<<"here"<<endl;
    
        for(int i=k+1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                //cout<<i<<" "<<j<<endl;
                mem(vis,0);
                dfs(i,j);
            }
            for(int j=1;j<=n;j++)//更新列标记
                visc[j][nmap[i][j]] = 1;
        }
    
        puts("yes");
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<n;j++)
                printf("%d ",nmap[i][j]);
            printf("%d
    ",nmap[i][n]);
        }
    
        return 0;
        f:;
            puts("no");;;
        return 0;
    }

    ;

      

  • 相关阅读:
    jquery对同级的td做radio限制
    "javascript:void(0)"用法
    SQL 插入查询的最大ID 号 进行批量
    Java数字、货币值和百分数等的格式化处理
    PHP 注意问题
    Android Fragment真正意义上的onResume和onPause
    Android_CodeWiki_03
    Android_CodeWiki_02
    Android_CodeWiki_01
    Android 启动APP黑屏解决方案
  • 原文地址:https://www.cnblogs.com/minun/p/10811652.html
Copyright © 2020-2023  润新知