简单思维 AtCoder - 2152

问题:

有n个盒子装有若干糖果,每次吃一个,求最少吃几个,使得每相邻的两个盒子的糖果数的和为x。

输入:

输入分两行,第一行包含整数n和x,
第二行输入n个数,分别表示每个盒子里糖果的个数;
(2<=n<=1e5,0<=ai<=1e9,0<=x<=1e9)

输出:

一个整数,表示最少吃多少个糖果。


分析:

一道简单的思维题,

既然使每相邻两个盒子的糖果个数都为x,那么直接枚举判断就可以了。,如果两个盒子糖果个数的和 > x ,就 - x

  !我首先是这样想的,但是,问题来了,如果这样的话就不知道吃掉的究竟是哪个盒子的糖果,也就无法继续判断了,这是这个题的难点。

其实不用考虑这些!!!!,将每相邻的两组都看作 a,b。。。。a+b>x 时,直接令,b=x-a,(a<=x的前提下)。s+=a+b-x

当a+b

这样的得到的 s  一定是最少的。(有些难理解)

绝对不会出现连续两次 a+b

这样的情况只会出现在中间,

所以在实际的操作中,如果出现这样的情况,可以理解为 两边的向中间补。两边两组分别取的个数一定是不变的,

还是举例说明吧!

如 :

                                                     5  4  2  3      x =  4.

正确的答案是:                           1  3  1  3      s = 6

按照上面的思路  得到的是:       4  0  2  2      s = 6


这个列子可分为 3 组  ,第 1 组取了  5 个,,第 3 组取了一个,第 2 组没有取。

不论是哪种方法,这个事实是不会改变的!!!!!!!

#include 
#include 


int main()
{
    int n,i,x;
    scanf("%d %d",&n,&x);
    long long ans=0,sum,a,b;
    scanf("%lld",&a); //第一个 盒子中的糖果个数
    if(a>x)   // x 是最后每个盒子要剩余的个数,  如果第一个盒子的糖果个数a大于x
    {
       ans+=a-x;  //  ans 是多出的个数
       a=x; 
    }

    for( i=1; ix)
        {
            ans+=sum-x;
            a=b-sum+x;   
        }
        else a=b;       
    }                   
    printf("%lld",ans); // 
    return 0;
}





















你可能感兴趣的:(acm题目)