Ryouko's Memory Note

题目意思:一个书有 n 页,每页的编号依次从 1 到 n 编排。如果从页 x 翻到页 y,那么|x-y|页都需要翻到(联系生活实际就很容易理解的了)。接着有m pieces 的 information,第 i piece 的information 在第 a[i] 页。为了减少翻页的页数,允许把某一页的信息,完全搬到某一页上,这个操作只可以执行一次。问应该把哪一页的信息搬到某一页上,从而使得翻页次数最少。

使用vector记录一个数两边的数字,然后把这些数字排序,选中间的那个当做修改后的值.

#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

const int MAX = 100100;
int a[MAX];
vector<int>ne[MAX];//相邻页
int fabs(int x)
{
    if(x<0)x=-x;
    return x;
}
int main()
{
    int n,m;
    int i,j;
    int tmp1,tmp2;
    long long sum1,sum2,maxdis;
    long long ans;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(i=0;i<m;i++)
            scanf("%d",&a[i]);

        for(i=0;i<m-1;i++)//statistics
        {
            if(a[i]!=a[i+1])
            {
                ne[a[i]].push_back(a[i+1]);
                ne[a[i+1]].push_back(a[i]);
            }
        }

        maxdis = 0;
        ans=0;
        for(i=1;i<=n;i++)//sort
        {
            if(!ne[i].empty())
            {
                sort(ne[i].begin(),ne[i].end());
                tmp2 = ne[i].size()/2;
                tmp1 = ne[i][tmp2];
                sum1=0;
                sum2=0;
                for(j=0;j<ne[i].size();j++)
                {
                    sum1+=fabs(ne[i][j]-tmp1);
                    sum2+=fabs(ne[i][j]-i);
                }
                maxdis = max(maxdis,sum2-sum1);
                ans+=sum2;// total turn page former
            }
        }
        printf("%I64d
",ans/2-maxdis);
        for(i=1;i<=n;i++)
            ne[i].clear();
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/XDJjy/p/3753675.html