poj 1844 Sum

来源:互联网 发布:vscode github token 编辑:程序博客网 时间:2024/06/05 19:33
//这题如果仔细一点儿分析,结果就出来了!题意:给出一个数,通过从1到N的连续数的运算而得出这个数//(两个数之间的符号只可以是+或-),求最小的N。 //先通过求从1到N的前N项和,如果是小于这个num数的,肯定满足不了,所以继续相加!如果是可以等于num的情况之下,就得出了结果,可以输出!//如果找不到相加和等于num这个数的,就肯定是大于这个num数的了,就只有通过变换数与数之间的符号(即换成-号)来得出这个数了!// 可以通过一个具体的样例分析:例如num=12;当1+2+3+4+5得出15时,用15-12=3,而要在1到5之间找出一个数*2等于3的数(为什么要乘以2?因为之前的是相加,你要从这个数列中减去这个数,当然是要减去两次啦),//没有满足的,所以继续加下去:1+2+3+4+5+6 = 21,而21-12=9,又和上面的情况相同,满足不了,继续,1+2+3+4+5+6+7 = 28,而28-12=16,满足了,就可以输出,因为求的是最小的N值! //下面是论坛上的解释,比我的要清楚:/*我也是看了各位大牛的讨论才明白的, 我把它写的更加具体点了而已一:sum一定要大于或等于输入的S.(等于时就已经找到了答案)   小于的话就算全做加法运算也不能达到S。             二:在满足第一条的情况下,注意一定要满足第一条后   第一次碰到(sum - S ) % 2 == 0  这里( sum = 1 + 2  + .... + i )这时的i就是答案。  证明如下:             1:若res是奇数,就说明res = ( 1 + 2 + ... + i )- S 是奇数             也就是说无论你怎么改变sum( sum = 1 + 2  + .... + i )的表达式             (当然是通过改变其中的加号为减号)也无法让res为0             举个例子吧:S = 5, sum = 1+2+3 = 6, res = 6 - 5 = 1;           无论改变(1+2+3)中的加号也没用,这是因为你在sum中改变一个加号为减号             时它的值就一定减少了一个偶数值(这是显然的)sum-S仍然为奇数             2:令res = sum - S,则res一定是0,2, 4, 6....中的一个             下面说明总可以通过改变sum表达式中的某几个加号为减号使得res为0             当k = 0的情况就不用说明了吧, 假设2k表示res 显然k = 1 2 3 4...            当k = 1 时可以通过把sum( sum = 1 + 2 + ... + i )            改成( sum = -1 + 2 + ... + i )            当k = 2 时可以通过把sum ( sum = 1 + 2 + ... + i )            改成( sum = 1 - 2 + ... + i )             一次类推res总可以变为0*/ #include <iostream>using namespace std;int main(){    int num, i, tmp, sum = 0;    cin >> num;     for (i = 1; ; i++){         sum += i;         tmp = sum - num;          if (tmp >= 0 && tmp % 2 == 0){              cout << i << endl;              break;          }     }         system("pause"); } 

原创粉丝点击