谷歌2014年中国区应届毕业生校园招聘B轮机试第一题——数独问题的解法(C++实现)

      今天做了一下谷歌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;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值