3*3 的矩阵,值限定为1-9不重复,已知横竖的和,和一个斜着的值,求这个矩阵,有啥快速的方法没?

shiter
人工智能领域优质创作者
博客专家认证
2015-08-25 05:43:14
3*3 的矩阵,值限定为1-9不重复,已知横竖的和,和一个斜着的值,求这个矩阵,有啥快速的方法没?

x x x 11
x x x 15
x x x 19
14 15 15 16
...全文
516 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-08-27
  • 打赏
  • 举报
回复
引用 13 楼 mujiok2003 的回复:
全排列才9!, 很容易穷举啊。
同意。
super_admi 2015-08-27
  • 打赏
  • 举报
回复
1 1 1 0 0 0 0 0 0 11 0 0 0 1 1 1 0 0 0 15 0 0 0 0 0 0 1 1 1 19 1 0 0 1 0 0 1 0 0 16 0 1 0 0 1 0 0 1 0 14 0 0 1 0 0 1 0 0 1 15 1 0 0 0 1 0 0 0 1 15 单纯形。
super_admi 2015-08-27
  • 打赏
  • 举报
回复
将这玩意列出方程,是不是用单纯形法就做出来了?
糊狐 2015-08-27
  • 打赏
  • 举报
回复
是用高等代数的方法做简化。不过注意,看上去七个方程,但相互独立的只有六个。所以需要给出三个新方程。选择三个不一线的位置,假设值即可。 所以最后的情况考虑A93 =494种。 大大减少
GKatHere 2015-08-26
  • 打赏
  • 举报
回复
找到最小那一行(列), 三个数按1,1,1,2,2,2,...这样多小到大测试, 所有其余二数取平均值开始,另外方向和大的先取大,再取小。。。 这样或许命中高些
zilaishuichina 2015-08-26
  • 打赏
  • 举报
回复
全排列,然后检查是否满足条件


template <typename T>
void swap(T* array, unsigned int i, unsigned int j)
{
T t = array[i];
array[i] = array[j];
array[j] = t;
}

void FullArray(int* array, size_t array_size, unsigned int index)
{
if (index >= array_size)
{
if ((array[0] + array[1] + array[2] == 11) &&
(array[3] + array[4] + array[5] == 15) &&
(array[6] + array[7] + array[8] == 19) &&
(array[0] + array[3] + array[6] == 16) &&
(array[1] + array[4] + array[7] == 14) &&
(array[2] + array[5] + array[8] == 15) &&
(array[0] + array[4] + array[8] == 15))
{
printf("%d,%d,%d\n", array[0], array[1], array[2]);
printf("%d,%d,%d\n", array[3], array[4], array[5]);
printf("%d,%d,%d\n\n", array[6], array[7], array[8]);
}

return;
}

for (unsigned int i = index; i < array_size; ++i)
{
swap(array, i, index);

FullArray(array, array_size, index + 1);

swap(array, i, index);
}
}

int main(int argc, char* argv[])
{
int value[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

FullArray(value, 9, 0);
}


paschen 版主 2015-08-26
  • 打赏
  • 举报
回复
也就9个数,不允许重复,可以用穷举法,总共有9的阶乘种可能 另外,如果有某行/列之和大于18,则1不可能在这一行/列,如楼主给的第三行
二班的码农 2015-08-26
  • 打赏
  • 举报
回复
这个就不知道了,这个好像可以用线性代数简化,9个未知数,7个等式,外加一个不能重复且只能在1~9的条件
shiter 2015-08-26
  • 打赏
  • 举报
回复
引用 5 楼 ant2012 的回复:
[quote=引用 4 楼 wangyaninglm 的回复:] [quote=引用 2 楼 houkaihua 的回复:] 列之和相加44…… lz 此题无解
为啥,没有解呢。。。[/quote] 2楼说的对,此题无解,11 + 15 = 19 != 14 + 15 +15[/quote] 改了,一下,抄错了,有没有什么简单办法。。
shiter 2015-08-26
  • 打赏
  • 举报
回复


// puzzl.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

// puzzle.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <vector>
#include <set>
#include <iostream>

using namespace std;

int result[3][3] = {0};

bool check(int a, int b, int c, int sum)
{
 if((a + b  + c )== sum)
  return true;
 else 
  return false;
}

int lastValue(int a, int b,int sum)
{
 return (sum - a - b);
}

//min max
vector<vector<int> > zuhe(int min,int max,int sum)
{

 vector<vector<int> > quanji;
 for(int i = min;i < max; ++i)
 { 
  for(int j = 1;j < max; ++j)
  {
   if(i + j > sum)
    continue;
   else
   {
    for(int k = 1; k <max ;++k)
    {
     if(check(i,j,k,sum))
     {
      vector<int> ziji;
      ziji.push_back(i);
      ziji.push_back(j);
      ziji.push_back(k);
      if (i!=j&&j!=k&&i!=k)
      {
       quanji.push_back(ziji);
      }
      
      
     }
     else
     {
      continue;
     }
    }
   }
  }

 }

 return quanji;
}

vector<vector<int> > filter_zuhe(int key,vector<vector<int> > temp)
{
 vector<vector<int> >::iterator iter ;
 for(iter = temp.begin(); iter!=temp.end(); )
 {
  if( (*iter)[0] != key)
   iter = temp.erase(iter);
  else
   iter ++ ;
 }

 return temp;
}


bool isOk()
{
	set<int> mySet;

	for(int i = 0;i <3; ++i)
	{
		for(int j = 0;j<3;++j)
		{
			if(result[i][j]>0&&result[i][j]<10)
			{
				mySet.insert(result[i][j]);
			}
		}
	}

	if(mySet.size()!=9)
	{return false;}
	else
	{
		if(mySet.size()==9)
		{
			for(int i = 0;i <3; ++i)
			{
				cout <<endl;
				for(int j = 0;j<3;++j)
				{
					cout<<result[i][j]<<" ";
				}
			}

			return true;
		}
	}
}

void dayin()
{
	for(int i = 0;i <3; ++i)
			{
				cout <<endl;
				for(int j = 0;j<3;++j)
				{
					cout<<result[i][j]<<" ";
				}
			}

	cout<<endl;
}

void qingling()
{
	for(int i = 0;i <3; ++i)
	{
		for(int j = 0;j<3;++j)
		{
			(result[i][j]=0);
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
 vector<vector<int> > quanjiheng = zuhe(1,9,11);
 vector<vector<int> > quanjishu = zuhe(1,9,16);
 vector<vector<int> > quanjixie = zuhe(1,9,15);

 int sizeheng = quanjiheng.size();
 int sizeshu = quanjishu.size();
 int sizexie = quanjixie.size();

 int key = 0,last_key = 0;

 vector<vector<int> > quanjishufilter;
 vector<vector<int> > quanjixiefilter;

 for(int i = 0;i < sizeheng ; ++i)
 {
	   key = quanjiheng[i][0];
	   if (key!=last_key)
	   {
		quanjishufilter = filter_zuhe(key,quanjishu);
		quanjixiefilter = filter_zuhe(key,quanjixie);
	   }
	   last_key = key;
	   //给横行赋值
	  for (int j = 0;j< 3;++j)
	  {
	   result[0][j] = quanjiheng[i][j];
	  
	  }
  
	  int sizeshu = quanjishufilter.size();
	  for (int k = 0; k< sizeshu;++k)
	  {
		  //给竖行赋值
		  for(int j = 0;j<3;++j)
		  {
			   result[j][0] = quanjishufilter[k][j];
		  }

		  int sizexie = quanjixiefilter.size();
		  for(int x = 0; x < sizexie; ++x)
		  {
			  for(int j = 0; j < 3 ;++j)
			  {
				  result[j][j] = quanjixiefilter[x][j];
			  }
				result[2][1] = 14 - result[0][1]-result[1][1];
				result[1][2] = 15-  result[1][0]-result[1][1];
				if(isOk())
				{
					//dayin();
					getchar();
					//return 0;
				}
				else
				{
					
					
				}
		  }

	
	 }

   qingling();
  
 }
 

 getchar();
 system("pause");
 return 0;
}





shiter 2015-08-26
  • 打赏
  • 举报
回复
啊,傻逼了,应该是竖着的,11 15 19 15 横着的16 14 15
二班的码农 2015-08-26
  • 打赏
  • 举报
回复
引用 4 楼 wangyaninglm 的回复:
[quote=引用 2 楼 houkaihua 的回复:] 列之和相加44…… lz 此题无解
为啥,没有解呢。。。[/quote] 2楼说的对,此题无解,11 + 15 = 19 != 14 + 15 +15
shiter 2015-08-26
  • 打赏
  • 举报
回复
引用 2 楼 houkaihua 的回复:
列之和相加44…… lz 此题无解
为啥,没有解呢。。。
jiqiang01234 2015-08-26
  • 打赏
  • 举报
回复
Sūdoku
糊狐 2015-08-26
  • 打赏
  • 举报
回复
列之和相加44…… lz 此题无解
mujiok2003 2015-08-26
  • 打赏
  • 举报
回复
全排列才9!, 很容易穷举啊。
lin5161678 2015-08-25
  • 打赏
  • 举报
回复
一般是做一个全排列 然后 检查相加结果

64,720

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧