[leetcode] 782. Transform to Chessboard

441 篇文章 0 订阅
284 篇文章 0 订阅

Description

An N x N board contains only 0s and 1s. In each move, you can swap any 2 rows with each other, or any 2 columns with each other.

What is the minimum number of moves to transform the board into a “chessboard” - a board where no 0s and no 1s are 4-directionally adjacent? If the task is impossible, return -1.

Examples:
Input:

board = [[0,1,1,0],[0,1,1,0],[1,0,0,1],[1,0,0,1]]

Output:

2

Explanation:

One potential sequence of moves is shown below, from left to right:
0110     1010     1010
0110 --> 1010 --> 0101
1001     0101     1010
1001     0101     0101

The first move swaps the first and second column.
The second move swaps the second and third row.

Input:

board = [[0, 1], [1, 0]]

Output:

0

Explanation:

Also note that the board with 0 in the top left corner,
01
10

is also a valid chessboard.

Input:

board = [[1, 0], [1, 0]]

Output:

-1

Explanation:

No matter what sequence of moves you make, you cannot end with a 
valid chessboard.

Note:

  • board will have the same number of rows and columns, a number in the range [2, 30].
  • board[i][j] will be only 0s or 1s.

分析

题目的意思是:一个n*n的网格里包含0和1,你可以交换任意的行和列,把这个网格变成棋盘,棋盘中的0和1都不是四面相邻的。

  • 这道题比较难,是hard类型的题目。
  • 在一个合法的棋盘里面,仅有两种行,这两种行是互逆的,例如有一行是:01010011,其他行一定是01010011或者10101100。列也是一样。
  • 一个推论为:矩形棋盘的左上,左下,右上,右下一定是4个1,或者两个1和两个0,或者4个0.
  • 另一个重要的属性是每行和每列有一半是1。假设这个棋盘是n*n:如果N=2k,每一行和每一列都包含k个1,如果N=2k+1,每一行和每一列有k个1和k+1个0,或者k+1个1和k个0.

代码

class Solution {
public:
    int movesToChessboard(vector<vector<int>>& board) {
        int n=board.size(),rowSum=0,colSum=0,rowSwap=0,colSwap=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(board[0][0]^board[i][0]^board[0][j]^board[i][j]){
                    return -1;
                }
            }
        }
        for(int i=0;i<n;i++){
            rowSum+=board[i][0];
            colSum+=board[0][i];
            rowSwap+=board[i][0]==i%2;
            colSwap+=board[0][i]==i%2;
        }
        if(n/2>rowSum||rowSum>(n+1)/2) return -1;
        if(n/2>colSum||colSum>(n+1)/2) return -1;
        if(n%2){
            if (colSwap % 2) colSwap = n - colSwap;
            if (rowSwap % 2) rowSwap = n - rowSwap;
        }else{
            colSwap=min(n-colSwap,colSwap);
            rowSwap = min(n - rowSwap, rowSwap);
        }
        return (colSwap+rowSwap)/2;
    }
};

参考文献

782. Transform to Chessboard

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值