数螃蟹(思路题)

B. 数螃蟹

Time limit per test: 2.0 seconds

Memory limit: 512 megabytes

kblack 在做数螃蟹的实验。按照「螃蟹爷爷的秘诀」一书上介绍的:由于东方神秘力量的影响,螃蟹的个数是一个完美的等差数列,例如:2,1,0,1,2,。是的,kblack 的螃蟹比较神奇,有的时候螃蟹的个数可能会是负的。

kblack 每天都去池塘记录螃蟹的个数。但是 kblack 自己给自己放了最多三天的假(也有可能两天,有可能一天,有可能不放),放假的时候螃蟹个数的记录就是 kblack 口胡的,有的时候会假得有点过分。

现给出 kblack n 天的记录,记录中至多有三个数是错误的。请纠正错误并输出正确的实验记录。

Input

第一行是一个整数 n (3n105)。

第二行给出 n 个整数:a1,a2,,an (|ai|109)。

Output

输出正确的实验记录:n 个整数 b1,b2,,bn。输出应是一个等差数列,与输入的数列至多有三个数不同,且保证 |bi|1018

题目保证有解。如果有多解输出任意一解。

Examples

Input
5
1 2 4 4 5
Output
1 2 3 4 5
Input
4
1 3 5 7
Output
1 3 5 7
Input
4
2 3 3 3
Output
4 3 2 1
思路:因为这个数列最多只有三个错误的数据,所以我们只要枚举前四个数,然后分别以前四个数为标准用其他数跟这个数来计算公差d出现的次数,正确的d一定是出现次数最多的那个。当数列的个数少于五个数时,我们只要随便输出n个一样的数即可,这个数必须是出现过的。
#include<stdio.h>
#include<string.h>
#include<map>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
const int N=1e5+10;
map<double,int>mapp;//mapp存公差d出现的次数,因为有些值是错误的,会造成d是double型数据,所以要开double
LL a[N],ans,b[N];
int sum,k;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lld",&a[i]);
    if(n<5)
        for(int i=0;i<n;i++)
            printf(i==n-1?"%lld\n":"%lld ",a[0]);
    else
    {
        sum=0;
        mapp.clear();//以第一个数为准,遍历找公差d
        for(int i=1;i<n;i++)
        {
            if(++mapp[(double)(a[i]-a[0])/i]>sum)//注意double强制转换
            {
                ans=(a[i]-a[0])/i;
                sum=mapp[(double)(a[i]-a[0])/i];
                k=i;
            }
        }
        mapp.clear();//以第二个数为准遍历找公差d,并且mapp要清零
        if(++mapp[(double)(a[1]-a[0])]>sum)
        {
            ans=a[1]-a[0];
            sum=mapp[(double)(a[1]-a[0])];
            k=1;
        }
        for(int i=2;i<n;i++)
        {
            if(++mapp[(double)(a[i]-a[1])/(i-1)]>sum)
            {
                ans=(a[i]-a[1])/(i-1);
                sum=mapp[(double)(a[i]-a[1])/(i-1)];
                k=i;
            }
        }
        mapp.clear();//以第三个数为准遍历找公差d
        if(++mapp[(double)(a[2]-a[0])/2]>sum)
        {
            ans=(a[2]-a[0])/2;
            sum=mapp[(double)(a[2]-a[0])/2];
            k=2;
        }
        if(++mapp[(double)(a[2]-a[1])]>sum)
        {
            ans=a[2]-a[1];
            sum=mapp[(double)(a[2]-a[1])];
            k=2;
        }
        for(int i=3;i<n;i++)
        {
            if(++mapp[(double)(a[i]-a[2])/(i-2)]>sum)
            {
                ans=(a[i]-a[2])/(i-2);
                sum=mapp[(double)(a[i]-a[2])/(i-2)];
                k=i;
            }
        }
        mapp.clear();//以第四个数为准遍历找公差d
        if(++mapp[(double)(a[3]-a[0])/3]>sum)
        {
            ans=(a[3]-a[0])/3;
            sum=mapp[(double)(a[3]-a[0])/3];
            k=3;
        }
        if(++mapp[(double)(a[3]-a[1])/(3-1)]>sum)
        {
            ans=(a[3]-a[1])/(3-1);
            sum=mapp[(double)(a[3]-a[1])/(3-1)];
            k=3;
        }
        if(++mapp[(double)(a[3]-a[2])]>sum)
        {
            ans=a[3]-a[2];
            sum=mapp[(double)(a[3]-a[2])];
            k=3;
        }
        for(int i=4;i<n;i++)
        {
            if(++mapp[(double)(a[i]-a[3])/(i-3)]>sum)
            {
                ans=(a[i]-a[3])/(i-3);
                sum=mapp[(double)(a[i]-a[3])/(i-3)];
                k=i;
            }
        }
        b[k]=a[k];
        for(int i=k-1;i>=0;i--)
            b[i]=b[i+1]-ans;
        for(int i=k+1;i<n;i++)
            b[i]=b[i-1]+ans;
        for(int i=0;i<n;i++)
            printf(i==n-1?"%lld\n":"%lld ",b[i]);
    }
}


猜你喜欢

转载自blog.csdn.net/never__give__up/article/details/80311852
今日推荐