问题描述:
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>