zoukankan      html  css  js  c++  java
  • UVa 10025 The ? 1 ? 2 ? ... ? n = k problem

     The ? 1 ? 2 ? ... ? n = k problem 

    The problem

    Given the following formula, one can set operators '+' or '-' instead of each '?', in order to obtain a given k
    ? 1 ? 2 ? ... ? n = k

    For example: to obtain k = 12 , the expression to be used will be:
    - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 
    with n = 7

    The Input

    The first line is the number of test cases, followed by a blank line.

    Each test case of the input contains integer k (0<=|k|<=1000000000).

    Each test case will be separated by a single line.

    The Output

    For each test case, your program should print the minimal possible n (1<=n) to obtain k with the above formula.

    Print a blank line between the outputs for two consecutive test cases.

    Sample Input

    2
    
    12
    
    -3646397
    

    Sample Output

    7
    
    2701
    

    Alex Gevak
    September 15, 2000 (Revised 4-10-00, Antonio Sanchez)

    题目的意思是说,在从1~n这n个数之间,通过添加+、-号使表达式的值为k,求这样的n最小为多少

    通过列举前几个n的值可以组合出的k,很容易发现规律:

    n=1 : k=1,-1

    n=2 :   k=3,-3,1,-1

    n=3 :   k=6,-6,4,-4,2,-2,0

    n=4 :   k=10,-10,8,-8,6,-6,4,-4,2,-2,0

    n=5 :   k=15,-15,13,-13,11,-11,9,-9,7,-7,5,-5,3,-3,1,-1,0

    ……     ……

    可以看出,当(n+1)/2向下取整为奇数时,可以组合出不大于n(n+1)/2的所有奇数

    当(n+1)/2向下取整为偶数时,可以组合出不大于n(n+1)/2的所有偶数

    按照以上规律写程序求解n即可

    WA了3次,第一次发现了把浮点数转化为它向上取整的整数时写的有问题,第二次发现当k=0时需要特殊判断,第三次发现在解二次方程求出的那个表达式中有8*k这个会溢出int的范围,要强制类型转换一下

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     int kase;
    10 
    11     scanf("%d",&kase);
    12 
    13     while(kase--)
    14     {
    15         int k;
    16 
    17         scanf("%d",&k);
    18 
    19         if(k<0)
    20             k=-k;
    21 
    22         double temp=(sqrt(8*((long long)k)+1)-1)/2;
    23         int n=temp;
    24 
    25         if(fabs(temp-n)>1e-9)
    26             n++;
    27 
    28         bool even=(k%2==0);
    29 
    30         if(even)
    31             while(((n+1)/2)%2)
    32                 n++;
    33         else
    34             while(((n+1)/2)%2==0)
    35                 n++;
    36 
    37         printf("%d
    ",k==0?3:n);
    38         if(kase)
    39             printf("
    ");
    40     }
    41 
    42     return 0;
    43 }
    [C++]
  • 相关阅读:
    poj 4005 Moles
    牛客 2C 圈圈
    牛客 2B 树 (组合计数)
    AC日记——校门外的树(增强版) 洛谷 P1276
    AC日记——寻找道路 洛谷 P2296
    AC日记——挤牛奶 洛谷 P1204
    AC日记——最大数 洛谷 P1198 [JSOI2008]
    AC日记——中位数 洛谷 P1168
    AC日记——校门外的树 洛谷 P1047
    AC日记——约瑟夫问题 codevs 1282
  • 原文地址:https://www.cnblogs.com/lzj-0218/p/3518733.html
Copyright © 2011-2022 走看看