简单思维 AtCoder

来源:互联网 发布:python上传图片步骤 编辑:程序博客网 时间:2024/05/22 19:34

问题:

有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<x 时  ,不用管!!!直接a = b,继续下面的判断!!

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

绝对不会出现连续两次 a+b<x 的情况。且第一组与最后一组a+b绝对不会<x. .

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

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

还是举例说明吧!

如 :

                                                     5  4  2  3      x =  4.

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

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


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

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

#include <stdio.h>#include <stdlib.h>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; i<n; i++) //剩下的 n-1 个盒子    {        scanf("%lld",&b);          sum=a+b;        if(sum>x)        {            ans+=sum-x;            a=b-sum+x;           }        else a=b;           }                       printf("%lld",ans); //     return 0;}





原创粉丝点击