1. 程式人生 > >codeforces+C. Ehab and a 2-operation task+構造題

codeforces+C. Ehab and a 2-operation task+構造題

題目連結:http://codeforces.com/contest/1088/problem/C
題目大意:給你長度為n一個序列,你有兩種操作
操作1:選擇一個座標i,對於對所有j<=i, a[j]+=x, 0≤x≤10^6
操作2:選擇一個座標i,對於對所有j<=i, a[j]%=x, 1≤x≤10^6
現在讓你最多進行n+1次操作,讓你輸出操作,讓序列成為一個嚴格單增的序列的每一次操作。
在這裡插入圖片描述

輸出:k次操作
對於操作的輸出格式:操作 i x

思路:我們開始想到就進行n+1次操作。用n次操作1,1次操作2。然後就從前往後構造0到n-1。一直有問題,構造後面的時候,無法消除對前面數字的影響。然後隊友突然冒出來一句必須從前往後構造,好了,我的思路可以AC了。先從後往前構造把第i數字構造成 i+k*n(k>=0的整數),然後再全部%n就OK了。

思考:第一次做這樣的題,不太熟練,尤其是怎麼消除對已經構造好的數字的影響。這次學到了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

ll a[2005];
int main()
{
	ll n, q=1;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        if(i!=1&&a[i]<=a[i-1])
        {
            q=0;
        }
    }
    if(q)
    {
        printf("0\n");
        return 0;
    }
    for(int i=1;i<=n;i++)
        a[i]%=n;
    ll p=n-1, k=0;/*p當前數字應該構造的數字*/
    if(n==1)
    {
        printf("0\n");
        return 0;
    }
    printf("%lld\n",n+1);
    for(int i=n;i>=1;i--)
    {
        a[i]=(a[i]+k)%n;
        if(a[i]<p)
        {
            printf("1 %d %lld\n",i, p-a[i]);
            k+=p-a[i];
            k%=n;
        }
        else if(a[i]==p)
        {
            printf("1 %d 0\n",i);
            p--;
            continue;
        }
        else
        {
            printf("1 %d %lld\n",i, p-a[i]+n);
            k+=p-a[i]+n;
            k%=n;
        }
        p--;
    }
    printf("2 %lld %lld\n",n, n);

	return 0;
}