首页 > 代码库 > 数组数字加减乘得24问题

数组数字加减乘得24问题

问题描述:

1个程度为n(1<=n<=10000)的一维数组A,A[i]=i(1<=i<=n)。每次运算操作中,我们先删除该数组任意2个元素a和b,将这2个元素做加,减或乘(a+b,a-b,a*b)运算后会得到1个整数,再将该整数放进数组。如此进行n-1次运算操作后,数组将仅剩1个元素。问任意给定的n,有没有可能存在这样的运算操作序列使得数组A最后得到的数字为24?不存在,输出“NO”,存在,输出“YES”,并输出一种可行的运算序列。


分析:

这个问题乍一看感觉有点懵,因为每次选择都是随机选择两个数,用暴力解法的话,空间很大。

如果我们按照常规的思路:考虑第一次选哪两个数,第二次选哪两个数,...依次执行n-1次,最后得到一个数。沿着这个思路最后只能用暴力搜索答案,空间太大,不可行。

如果你仔细思考可能会发现这个问题有一个限制行极强的条件:A[i]=i。这就是说数组内容是从1到n的连续整数,不是任意的随机数字。跳出常规的思路,这道题有没有什么规律,可不可以用数论的知识解决?聪明的你也许会发现:

如果f(k)=24,则 f(K+2) = f(k)*((k+2)-(k+1))=24;!!  发现了吗

如果f(k)=24 ,则f(k+2x) 都可以等于24。(x = 1,2,3....)

我们很自然的想到了归纳法,所以我们需要找到前面的可以得出24的那个k。

f(4) = (1+2+3)*4 = 24   ,所以,所有大于4的偶数也都可以得到24;

f(5) = (5-2)*(1+3+4) = 24 , 所以,所有大于5的奇数都可以得到24;

从而大于等于4的n都可以得到24.

很明显的,n等于1,2,3时无法得到24.所以全域的解就得到了。

所以,有的时候,我们容易被一些已有的思维模式所束缚,如果能跳出常规的思维模式看问题,也许会得到意想不到的收获!



代码:

<span style="font-size:14px;">#include <iostream>

void Game24(int [] A, int n)
{
	using namespace std;
	if(n >= 4){
		cout << "YES"<<endl;
		if(n%2==0)
		{
			cout << "1+2 =3"<<endl;
			cout << "3+3 =6"<<endl;
			cout << "6*4 = 24"<<endl;

			while(int i = 4; i<=n-2; i++)
			{
				cout << i+2 << "-" << i+1<< "=" << 1 << endl;
				cout << "24*1 =24"<<endl;
			} 
		}
		else
		{
			cout << "5-2 =3"<<endl;
			cout << "1+3 =4"<<endl;
			cout << "4+4 = 8"<<endl;
			cout << "3*8 =24"<<endl;

			while(int i = 5; i<=n-2; i++)
			{
				cout << i+2 << "-" << i+1<< "=" << 1 << endl;
				cout << "24*1 =24"<<endl;
			} 
		}
	}
	else 
		cout << "NO" <<endl;

	return ;
}</span>



数组数字加减乘得24问题