本题比较难搞的是如何知道(x, y)属于哪个小方块, 对于(x / n, y / n) 如果得到(0,0)则属于第一个小方块,
得到(0,1)则属于第2个小方块....
因为(x / n, y / n)只会得到(0,0),(0,1),(0,2)…(1,0),(1,2)…之类的,于是可以定义get函数, 用来知道(0,0),(0,1),(0,2)…(1,0),(1,2)…属于哪个小方块
这样就可以知道(x / n, y / n)属于哪个小方块
#include<iostream>
#include<cstring>
using namespace std;
const int N = 40;
int sm[N][N];
bool row[N][N], col[N][N];
bool cell[N][N];
void get(int n){
for(int i = 0, k = 1; i < n; i++)
for(int j = 0; j < n; j++, k++)
{
sm[i][j] = k; /*sm[i][j] = k表示i,j属于第k个小方块*/
}
}
int main(){
int t;
cin >> t;
int r = 1;
while(t--){
memset(row, 0, sizeof row);
memset(col, 0, sizeof col);
memset(cell, 0, sizeof cell);
int n;
cin >> n;
get(n);
bool getNot = false; //getNot表示找到了不符合条件的点
for(int i = 0; i < n * n; i++) {
for(int j = 0; j < n * n; j++) {
int s = sm[i / n][j / n]; //看看当前的坐标属于哪个小方块
int x;
cin >> x;
if(row[i][x] || col[j][x] || cell[s][x] || x > n*n || x <= 0) getNot = true;
else row[i][x] = col[j][x] = cell[s][x] = true;
}
}
if(getNot) printf("Case #%d: ", r++), printf("No\n");
else printf("Case #%d: Yes\n", r++);
}
}