今天做了一下谷歌2013年校园招聘第二轮机试题,自己独立把程序写出来并且调试通过。
原题网址:https://code.google.com/codejam/contest/2929486/dashboard#s=p0
先说一下题目的大致意思:
1.输入一个整数N:3 ≤ N ≤ 6
2.输入一个N2xN2 阶矩阵
3.判断是否是数独:
数独必须同时满足以下三个条件:(1)每一行是从1到N2的互异整数
(2)每一列是从1到N2的互异整数
(3)把这个矩阵分为N2个不重叠的子矩阵,每个子矩阵包含1到N2的互异整数
例如:N = 3时,如图所示
是一个数独。
我的解题思路:
(1)先判断输入的数是否在1到N2范围内,如果不在,则说明不是数独。
(2)判断N2行和N2列是否是互异的元素:这里用到了标准库的容器set,把N2个数放入一个set中,然后调用set.size()函数,看其返回值是否等于N2,如果不等于N2,则不是数独。
(3)循环把N2个子矩阵的所有元素放入set中,然后调用set.size()函数,看其返回值是否等于N2,如果不等于N2,则不是数独。
下面直接上代码:
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <set>
using namespace std;
//判断一个n×n的矩阵的各行、各列元素是否互异
bool isSoduku(int *p,int n)
{
int i,j;
bool b1 = false;
bool b2 = false;
for(i = 0;i < n;i++)
{
set<int> rs;
for(j = 0;j < n;j++)
{
int temp = *(p + i*n + j);
rs.insert(temp);
}
if(n == rs.size())
b1 = true;
}
for(j = 0;j < n;j++)
{
set<int> cs;
for(i = 0;i < n;i++)
{
int t = *(p + i + j*n);
cs.insert(t);
}
if(n == cs.size())
b2 = true;
}
return (b1 && b2);
}
int main()
{
int T;
cin>>T;
bool *re = new bool[T];
for(int l = 0;l < T;l++)
re[l] = true;
for(int i = 0;i < T;i++)
{
int n;
cin>>n;
int **a = new int *[n*n];
for(int r = 0;r < n*n;r++)
a[r] = new int [n*n];
for(int j = 0;j < n*n;j++)
{
for(int k = 0;k < n*n;k++)
{
cin>>a[j][k];
if(a[j][k] < 1 || a[j][k] > n*n)
re[i] = false;
}
}
//如果输入的数不在1到N的平方的范围内,则继续测试下一个用例
if(!re[i])
continue;
//如果矩阵各行、各列的数不互异,则继续测试下一个用例
if(!isSoduku((int*)a,n*n))
{
re[i] = false;
continue;
}
else
{
bool con = true;
//循环测试N*N个子矩阵,看它们中的元素是否互异
for(int p = 0;p < n;p++)
{
if(!con)
break;
for(int q = 0;q < n;q++)
{
set<int> s;
for(int x = 0;x < n;x++)
{
for(int y = 0;y < n;y++)
s.insert(a[x + n*p][y + n*q]);
}
if(s.size() != n*n)
{
re[i] = false;
con = false;
break;
}
}
}
}
for(int num = 0;num < n*n;num++)
{
delete[] a[num];
}
delete a;
}
for(int i = 0;i < T;i++)
{
if(re[i])
cout<<"Case #"<<i+1<<":Yes"<<endl;
else
cout<<"Case #"<<i+1<<":No"<<endl;
}
delete re;
return 0;
}