分组

题目描述:
为了排出完美的拍照队形,班长想出了一种方法:他让全班人分成了n组,从左到右排开,每一组站在一起,第i组有ai个人。但是当他仔细观察时,发现他设计的分组方案并不对称。不对称就产生了很多问题,照片不好看还是其次的,最重要的一点是会影响公平性,最终影响班级团结,导致同学间失和。为了安抚烦躁的人群,班长必须用尽量简洁的方法来调整分组。由于场面混乱,他每次只能把相邻的两组人合为一组。他想知道,他最少需要多少次合并操作,才能让分组方案在数量上对称?
例如:一开始分了7组,人数分别为:2 5 3 2 8 1 1。
让第二和第三组合并,得到:2 8 2 8 1 1
再让最后两组合并,得到:2 8 2 8 2
这样只需要两次操作,在数量上就达到了对称。
输入:
第一行 n
第二行 n个数,a1到an。

输出
一个数,最少操作数。

数据范围:
分数 n
30 10
30 1000
40 10^6
ai为正整数,总和小于等于10^9

时间限制:1s

样例数据:
输入 输出
3
1 2 3 1
5
1 2 4 6 1 1
4
1 4 3 2 2

样例解释:
1 2 3 -> 3 3
1 2 4 6 1 -> 1 6 6 1
1 4 3 2 -> 5 3 2 -> 5 5


解法:本题是个明显贪心题,用从头到尾和从尾到头的方法。设置两个指针l和r,l从左往右,r从右往左,即可得出a[l+1]+=a[l]; a[r-1]+=a[r];这两个算式!核心√。直到a[l]==a[r]时才停止。或者是l==r时停止。(备注:a[l]>a[r]时,a[r]做运算,反之则a[l]做运算,当你不知道什么时候对a[l]或a[r]做运算,最好用函数。简单递归即可)
get代码如下:

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
typedef long long ll;
using namespace std;
int a[1000008],n,ans,l,r;
ll sum;
void fun(int x,int y){
    if(a[x]==a[y]){ l=x; r=y; return;}
    if(a[x]>a[y]){ a[y-1]+=a[y]; sum++; fun(x,y-1); return; }
    if(a[x]<a[y]){ a[x+1]+=a[x]; sum++; fun(x+1,y); return; }
    return;
} 
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    l=1; r=n;
    while(l<r){
        if(l==r) break;
        if(a[l]==a[r]) { l++; r--; continue; }
        fun(l,r); 
    }
    cout<<sum;
    return 0;
}

 

posted @ 2019-07-09 23:41  #Cookies#  阅读(212)  评论(0编辑  收藏  举报