CSU-暑假集训题 Equalize Them All

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

题目:

You are given an array a consisting of n

integers. You can perform the following operations arbitrary number of times (possibly, zero):

  1. Choose a pair of indices (i,j)

such that |ij|=1 (indices i and j are adjacent) and set ai:=ai+|aiaj|

  • ;
  • Choose a pair of indices (i,j)

such that |ij|=1 (indices i and j are adjacent) and set ai:=ai|aiaj|

  1. .

The value |x|

means the absolute value of x. For example, |4|=4, |3|=3

.

Your task is to find the minimum number of operations required to obtain the array of equal elements and print the order of operations to do it.

It is guaranteed that you always can obtain the array of equal elements using such operations.

Note that after each operation each element of the current array should not exceed 1018

by absolute value.

Input

The first line of the input contains one integer n (1n2105) — the number of elements in a

.

The second line of the input contains n

integers a1,a2,,an (0ai2105), where ai is the i-th element of a.

Output

In the first line print one integer k

— the minimum number of operations required to obtain the array of equal elements.

In the next k

lines print operations itself. The p-th operation should be printed as a triple of integers (tp,ip,jp), where tp is either 1 or 2 (1 means that you perform the operation of the first type, and 2 means that you perform the operation of the second type), and ip and jp are indices of adjacent elements of the array such that 1ip,jpn, |ipjp|=1

. See the examples for better understanding.

Note that after each operation each element of the current array should not exceed 1018

by absolute value.

If there are many possible answers, you can print any.

example

 
    Input
5
2 4 6 6 6
Output
2
1 2 3 
1 1 2 
Input
3
2 8 10
Output
2
2 2 1 
2 3 2 
Input
4
1 1 1 1
Output
0

思路

求序列就经过几次step变成同一个数,其实能发现一个数经过step1或者step2变成相邻的数,所以要经过最小次数变成同一个数字,就是先求出出现次数最多的数字,然后把所有的其他数字都变成这个数字。注意,出现次数最多的数字可能不相邻,序列是乱序的。

先记录数字的位置,然后从该位置往前遍历序列,比这个数字大,就执行step2,比这个数字小,就执行step1,结束后,再从该位置往后遍历,比这个数字大,就执行step2,比这个数字小,就执行step1.

AC代码

/*没说输入的序列的升序还是降序就表明是乱序,不要因为样例是升序就以为是升序 
*/
#include<iostream>
using namespace std;
const int MAX=2e5+10;
int a[MAX],b[MAX];
int main()
{
    int n;
    cin>>n;
    int maxx=0,num,pos=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[a[i]]++;
        if(b[a[i]]>maxx)
        {
            maxx=b[a[i]];
            pos=i;
        }
    }
    cout<<n-b[a[pos]]<<endl;
    if(pos>1)
    {
        int j=pos-1;
        for(;j>=1;j--)
        {
            if(a[j]==a[pos])continue;
            if(a[j]>a[j+1])cout<<2<<" "<<j<<" "<<j+1<<endl;
            else cout<<1<<" "<<j<<" "<<j+1<<endl;
            a[j]=a[pos];
        }
    }
    for(int k=pos+1;k<=n;k++)
    {
        if(a[k]==a[pos])continue;
        if(a[k]>a[k-1])cout<<2<<" "<<k<<" "<<k-1<<endl;
        else cout<<1<<" "<<k<<" "<<k-1<<endl;
        a[k]=a[pos];
    }
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xlbfxx/p/11255571.html