Codeforces Global Round 10——A.B!.C

Codeforces Global Round 10

A. Omkar and Password

题意:t组输入,每组n个数,数组a,可进行操作:相邻的两个值不同,则可以相加并替换掉这相邻的两个值,问最后数组剩余的长度最小值。
思路:只要数组里有超过两个不相同的数,就是可以相加得到最后只剩一个数。否则就是全部都相同的值,直接输出n。
代码

#include
using namespace std;
int T,n;
int a[200005];
map<int,int>mp;
int main()
{
    cin>>T;
    while(T--)
    {
        mp.clear();
        cin>>n;
        int num=0;
        for(int i=0; i<n; i++)
        {
            cin>>a[i];
            if(mp[a[i]]==0)
                num++,mp[a[i]]++;
        }
        if(num>1)
            printf("1\n");
        else
            printf("%d\n",n);
    }
    return 0;
}

B. Omkar and Infinity Clock

题意:t组输入,每组有n,还有一个k,接下来一行是n个数,数组a,k次操作,每次操作:用数组中最大值减去数组中每个数,替代原值,输出k此操作后的数组 。
思路:这道题的k的范围是1018次,这一看就不能直接暴力,所以用数据写一写,算一算,发现k次操作的奇数次都是一样的,偶数次都是一样的,那就直接判断k的奇偶,求出k=1次时的操作结果和k=2次时的操作结果即可。
但是真是没注意到,a数组的取值范围是-109,求最大值时,我定义的最大值的初始值是-1,唉。
代码

#include
using namespace std;
int T,n;
long long int a[200005],b[200005],c[200005];
long long int k;
map<int,int>mp;
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n>>k;
        long long  maxn=-0x3f3f3f3f3f3f;
        long long int minn=0x3f3f3f3f3f;
        for(int i=0; i<n; i++)
        {
            cin>>a[i];
            minn=min(a[i],minn);
            maxn=max(maxn,a[i]);
        }
        int num=0;
        for(int i=0; i<n; i++)
        {
            b[i]=maxn-a[i];
            if(b[i]==0)
                num++;
        }
        if(num==n)
        {
            for(int i=0; i<n-1; i++)
                printf("0 ");
            printf("0\n");
            continue;
        }
        for(int i=0; i<n; i++)
        {
            c[i]=maxn-minn-b[i];
        }
        if(k%2==0)
        {
            for(int i=0; i<n-1; i++)
                printf("%ld ",c[i]);
            printf("%lld\n",c[n-1]);
        }
        else
        {
            for(int i=0; i<n-1; i++)
                printf("%lld ",b[i]);
            printf("%lld\n",b[n-1]);
        }
    }
    return 0;
}

C. Omkar and Waterslide

题意:将给定的数组a,变成非递减序列的最少步骤。
思路:一起的都是递增的一个需要加的子序列或者递减的需要加的子序列,然后加最大的差距的差值。但是如果中间有突然增的就不好处理。于是就可以发现,如果数组与前面的值的差值是负数,那此负数的绝对值就是需要加的值,(如果是正数,那退回去想就是,随着上一个负数时跟着一起加的满足了),所以算出所有与前一位的值的差值,若是负数,就是需要操作,加上改负数的绝对值。
代码

#include
using namespace std;
int T,n;
int a[200005],b[200005];
long long int num;
map<int,int>mp;
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0; i<n; i++)
            cin>>a[i];
        b[0]=0;
        num=0;
        for(int i=1; i<n; i++)
        {
            b[i]=a[i]-a[i-1];
            if(b[i]<0)
                num+=abs(b[i]);
        }
        printf("%lld\n",num);
    }
    return 0;
}

你可能感兴趣的:(codeforces,思维)