zoukankan      html  css  js  c++  java
  • 分组

    题目描述:
    为了排出完美的拍照队形,班长想出了一种方法:他让全班人分成了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;
    }
  • 相关阅读:
    数据库设计优化(一)--基础
    数据库设计--范式原则
    迭代器 与 foreach 的区别
    DBeaver中如何调整SQL编辑器的字体大小
    腾讯课堂下载回放视频
    超级美味的大盘鸡做法
    关闭或开启Win10系统的自动更新
    geoserver发布地图瓦片影像数据
    使用GeoServer发布Shapfile数据
    GeoServer下载与安装(Windows版)
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11161260.html
Copyright © 2011-2022 走看看