• [ CodeVS冲杯之路 ] P1098


       不充钱,你怎么AC?

         题目:http://codevs.cn/problem/1098/

         显然就是使每堆牌达到总体的平均数,尽量使每次移动时的牌数最大,这就类似于飞行棋,将几个棋子叠起来一起走是最优的。

         我们将数组变为关于平均数的浮动,然后每次寻找距离最小的一正一负的两个位置,将绝对值小的补上,也就是将其中一个变为0(若绝对值相等就是两个),再从多的往少的一个个标记,代表会往那边移动一次。注意这里要开一个左一个右,因为向左和向右是代表的两种不同得方案。那么这样我们就达到了每次移动牌数尽可能最多。可能思路讲的不是很清晰,具体请参考代码。

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #define N 110
     8 using namespace std;
     9 
    10 struct data
    11 {
    12     int l,r;
    13 }
    14     f[N];
    15 int a[N];
    16 int main()
    17 {
    18     int i,n,k,sum,l,r;
    19     scanf("%d",&n);
    20     sum=0;
    21     for (i=1;i<=n;i++)
    22         {
    23             scanf("%d",&a[i]);
    24             sum+=a[i];
    25             f[i].l=f[i].r=0;
    26         }
    27     sum/=n;
    28     for (i=1;i<=n;i++) a[i]-=sum;
    29     l=r=1;
    30     while (1)
    31         {
    32             while (a[l]>=0&&l<=n) l++;
    33             while (a[r]<=0&&r<=n) r++;
    34             if (r>n||l>n) break;
    35             k=min(-a[l],a[r]);
    36             a[l]+=k;
    37             a[r]-=k;
    38             if (r>l) for (i=r;i>l;i--) f[i].l=1;
    39             else for (i=r;i<l;i++) f[i].r=1;
    40         }
    41     sum=0;
    42     for (i=1;i<=n;i++) sum+=f[i].l+f[i].r;
    43     printf("%d
    ",sum);
    44     return 0;
    45 }
  • 相关阅读:
    linux tcp中time_wait
    linux查看系统信息
    运行程序出错无法找到库文件
    安装keepalived
    python 深拷贝与浅拷贝
    python import eventlet包时提示ImportError: cannot import name eventlet
    [原创] 用两个queue实现stack的功能
    [原创] 用两个stack实现queue的功能
    [原创] 编写函数,实现对链表元素的排序与分类
    python 装饰器
  • 原文地址:https://www.cnblogs.com/hadilo/p/5861112.html
Copyright © 2020-2023  润新知