1. 程式人生 > >Vijos P1335 數獨驗證【謎題】

Vijos P1335 數獨驗證【謎題】

背景

XX學校風靡一款智力遊戲,也就是數獨(九宮格),先給你一個數獨,並需要你驗證是否符合規則。

描述

具體規則如下:
每一行都用到1,2,3,4,5,6,7,8,9,位置不限,
每一列都用到1,2,3,4,5,6,7,8,9,位置不限,
每3×3的格子(共九個這樣的格子)都用到1,2,3,4,5,6,7,8,9,位置不限,
遊戲的過程就是用1,2,3,4,5,6,7,8,9填充空白,並要求滿足每行、每列、每個九宮格都用到1,2,3,4,5,6,7,8,9。

如下是一個正確的數獨:
5 8 1 4 9 3 7 6 2
9 6 3 7 1 2 5 8 4
2 7 4 8 6 5 9 3 1
1 2 9 5 4 6 3 7 8
4 3 6 1 8 7 2 9 5
7 5 8 3 2 9 1 4 6
8 9 2 6 7 1 4 5 3
6 1 5 9 3 4 8 2 7
3 4 7 2 5 8 6 1 9

格式

輸入格式

輸入n個數獨,你來驗證它是否違反規則.
第一行為數獨個數,第二行開始為第一個數獨,之後為第二個,至第n個.
注意!每個數獨之間有一個回車隔開!

輸出格式

若正確則輸出”Right”若不正確則輸出”Wrong” 輸出一個換一行

樣例1

樣例輸入1

2
5 8 1 4 9 3 7 6 2
9 6 3 7 1 2 5 8 4
2 7 4 8 6 5 9 3 1
1 2 9 5 4 6 3 7 8
4 3 6 1 8 7 2 9 5
7 5 8 3 2 9 1 4 6
8 9 2 6 7 1 4 5 3
6 1 5 9 3 4 8 2 7
3 4 7 2 5 8 6 1 9

1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8

樣例輸出1

Right
Wrong

限制

各個測試點1s

提示

1<=n<=20 (輸入的數獨個數)
不論輸入的數獨是錯誤的還是正確的,資料都保證每個數在1-9之間,即只會出現因為有相同的數而導致違反規則,而不會因為數字超出了1-9的範圍而違反規則.

問題分析:需要做行、列和塊的值重複檢查。

程式說明

分別用3個數組來標記行、列和塊的值重複檢查。

程式中編寫函式getblock()用於將行和列的值轉換為塊的值。

即使知道結果,還需要把剩餘資料讀入,以便後續處理。

題記:(略)

AC的C++程式如下:

#include <iostream>
#include <cstring>

using namespace std;

const int N = 3;
const int SQUARE = N * N;
int row[SQUARE][SQUARE];
int col[SQUARE][SQUARE];
int block[SQUARE][SQUARE];

/* 行列下標轉換為塊下標 */
int getblock(int row, int col, int n)
{
    return (row / n) * n + col / n;
}

int main()
{
    int n, val, b;

    cin >> n;
    while(n--) {
        memset(row, 0, sizeof(row));
        memset(col, 0, sizeof(col));
        memset(block, 0, sizeof(block));

        bool okflag = true;
        for(int i=0; i<SQUARE; i++)
            for(int j=0; j<SQUARE; j++) {
                cin >> val;
                if(okflag) {
                    b = getblock(i, j, N);
                    if(row[i][val -1] || col[j][val - 1] || block[b][val - 1])
                        okflag = false;

                    row[i][val - 1] = 1;
                    col[j][val - 1] = 1;
                    block[b][val - 1] = 1;
                }
            }

        cout << (okflag ? "Right" : "Wrong") << endl;
    }

    return 0;
}