zoukankan      html  css  js  c++  java
  • CF820D Mister B and PR Shifts

    题目链接:http://codeforces.com/problemset/problem/820/D

    题目大意:

      给出一个(n)元素数组(p[]),定义数组(p[])的误差值为(sumlimits_{i=1}^{i=n} |p[i]-i|).每次操作都把下标为(n)的数放到下标为(1)的位置,其他数依次右移,问在通过几次操作后能使得误差值最小

    知识点:  (void)

    解题思路:

      见注释。

    AC代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=1e6+5;
     6 ll p[maxn],has[maxn<<1];
     7 
     8 int main(){
     9     ll n;
    10     ll bigger=0,smaller=0,equ=0,ans1=0,ans2=0;  //bigger 记录目前比其下标大的数的个数,small 记录比其下标小的,equ 记录等于其下标的,最终输出是 ans1 ans2
    11     scanf("%I64d",&n);
    12     for(ll i=1LL;i<=n;i++){
    13         scanf("%I64d",&p[i]);
    14         if(p[i]>i){
    15             bigger++;
    16             has[p[i]-i]++;  //has[X] 记录比下标大 X 的数的个数
    17         }
    18         else if(p[i]==i){
    19             equ++;
    20             has[0]++;
    21         }
    22         else    smaller++;
    23         ans1+=abs(p[i]-i);
    24     }
    25     ll temp=ans1;   //临时记录ans1
    26 
    27     //首先,请注意:我后面提到的数字其实都是数字与下标的差值,因为我们着重研究的是这个
    28     for(ll last=n-1LL,now=1LL;last>=1LL;last--,now++){  //last 记录目前下标为n的数的位置;now 记录目前是第几号变换,在此处理解为一条“零线”,除了下标为n的数之外的所有数减去 now 即为现在的数
    29         temp+=(equ+smaller);
    30         temp-=bigger;   //从 now-1 变换到 now 后,所有数的下标加一(不考虑下标为n的数),则原来小于或等于下标的数对于ans1的贡献值增大1,大于下标的数对于ans1的贡献值减小1
    31         
    32         smaller+=equ;   //原本等于下标的数都变成小于了
    33         bigger-=has[now];   //原本等于 now+1(即现在的now, 其实就是原本等于1)的数现在都变成了0
    34     //接下来处理之前下标是n,现在下标是1的数
    35         if(p[last+1]>=last+1LL)
    36             has[p[last+1]-last-1]--;    //先抹除其原来在has[]中的记录
    37         has[p[last+1]-1+now]++;     //重新记录,注意:此时的“零线”已经抬高了,相应的也要加上 now
    38         equ=has[now];   //新的equ其实就是那些现在在“零线”上的数
    39         if(p[last+1]>1LL)   bigger++;
    40         smaller=n-equ-bigger;   //显然,smaller + equ + bigger = n
    41 
    42         temp-=abs(p[last+1]-n-1LL); //特殊处理原本下标为n的数
    43         temp+=abs(p[last+1]-1LL);
    44         if(temp<ans1){
    45             ans1=temp;
    46             ans2=now;
    47         }
    48     }
    49     printf("%I64d %I64d
    ",ans1,ans2);
    50 
    51     return 0;
    52 }

      

    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    调整swt table的行高
    获取TableViewer里面的所有TableViewerColumn
    jface viewer 全选
    jaxb生成pojo类返回类型为布尔值的问题
    EMF中复制对象属性
    向导中的参数传递 wizard param
    GEF中TreeViewer的叶子节点展开
    Cannot modify resource set without a write transaction 问题
    注册emf package并读取EMF文件
    从运行时的工作空间获取EMF文件(IFILE)
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/8406359.html
Copyright © 2011-2022 走看看