纯粹的数学题,题目的意思是给你一组序列,让你能同时改变它的一个子序列,让其子序列的值增加1,或者减少1.

思路的话,就是找其中的数学规律,给你的序列例如是:3,5,1,4,7。先求出其序列的正差和=5-3+7-4=5;所以可以用最小的5步消除其差距。至于为什么嘛?直接用笔思考一下就可以办到了,再者,其不同的结果数是序列的头尾的差值的绝对值加1,这里要注意,并不是序列其中的最大值与最小值的差值。因为好比上面的那个序列。是不可能出现2,2,2,2,2这种情况的,因为要达到这种情况,那么改变的步数一定是超过5步的。因为如果改变之后序列中元素的值小于头尾其中的一个数,那么就不可能通过改变一段子序列的值来变换啦。我的语言表达能力有点差,sorry!

#include<iostream>
#include<cstring>
using namespace
std;
int
seq[1000009];
int
main(void)
{

    int
count=0,n,m,total,i;
    _int64 first,second,ans;
    cin>>n;
    while
(n--)
    {

        cin>>m;
        int
max=0xFFFFFFFF,min=0x7FFFFFFF;
        for
(i=0;i<m;i++)
            cin>>seq[i];
       
    //    cout<<max<<min<<endl;
        first=0,second=0;
        for
(i=1;i<m;i++)
        {

            if
(seq[i]-seq[i-1]>0)
                first+=seq[i]-seq[i-1];
            else

                second-=seq[i]-seq[i-1];
        }

        if
(first>second)
            ans=first;
        else

            ans=second;
   
        if
(seq[0]>seq[i-1])
        {

            min=seq[i-1];
            max=seq[0];
        }

        else

        {

            max=seq[i-1];
            min=seq[0];
        }

        //cout<<max<<"   "<<min<<endl;
        total=max-min+1;//求出头尾序列的差值并加1,为最终结果的总数
        /*cout<<"Case "<<++count<<": ";
        cout<<ans<<" "<<total<<endl;*/

        printf("Case %d: %I64d %d\n",++count,ans,total);
    }

    return
0;
}

posted on 2011-04-26 14:26  cchun  阅读(500)  评论(0编辑  收藏  举报