• (原创)Codeforces Round #550 (Div. 3) D. Equalize Them All


    D. Equalize Them All
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given an array aa consisting of nn integers. You can perform the following operations arbitrary number of times (possibly, zero):

    1. Choose a pair of indices (i,j)(i,j) such that |ij|=1|i−j|=1 (indices ii and jj are adjacent) and set ai:=ai+|aiaj|;
    2. Choose a pair of indices (i,j)(i,j) such that |ij|=1|i−j|=1 (indices ii and jj are adjacent) and set ai:=ai|aiaj| ; 

    The value |x||x| means the absolute value of xx . For example, |4|=4|4|=4 , |3|=3|−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 10181018 by absolute value.

    Input

    The first line of the input contains one integer nn (1n21051≤n≤2⋅105 ) — the number of elements in aa .

    The second line of the input contains nn integers a1,a2,,ana1,a2,…,an (0ai2105,0≤ai≤2⋅105 ), where aiai is the ii -th element of aa .

    Output

    In the first line print one integer kk — the minimum number of operations required to obtain the array of equal elements.

    In the next kk lines print operations itself. The pp -th operation should be printed as a triple of integers (tp,ip,jp)(tp,ip,jp) , where tptp is either 11 or 22 (11 means that you perform the operation of the first type, and 22 means that you perform the operation of the second type), and ipip and jpjp are indices of adjacent elements of the array such that 1ip,jpn1≤ip,jp≤n , |ipjp|=1|ip−jp|=1 . See the examples for better understanding.

    Note that after each operation each element of the current array should not exceed 10181018 by absolute value.

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

    Examples
    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
    

     解题思路:这道题就是说给你两个操作:

    选择1 :ai:=ai+|aiaj|;

    选择2 :ai:=ai|aiaj|

    问你如何通过最少操作数,使其元素全部变为相同;

    1)我们可先通过一个循环记录每个数出现的个数;

    2)通过循环找出出现次数最多的元素;并记录下标,这里记录的是出现次数最多的那个元素的最后的下标;

    3)由该元素向两边延申(主要是怕越界这个情况);向序号比它小的一边和向序号比它大的一边,分情况延申;

    4)特别注意输出的序号要往那个元素最多的序号靠,不然可能会有很多细节上的错误,比如越界等等,我在这里被坑了一个多小时,自己体会一下为什么要往元素最多的那个序号靠;

    代码如下:

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 int n ;
     6 int vis[200005];
     7 long long int a[200005];
     8 int maxn = -1;
     9 int flag = -1;
    10 int num = 0 ;
    11 int count1 = 0 ;
    12 int main()
    13 {
    14  
    15     cin>>n;
    16     for(int i = 1; i <= n ;i++)
    17     {
    18         cin>>a[i];
    19         vis[a[i]]++;             //用一个vis数组记录每个元素出现的个数;
    20     }
    21     for(int i = 1; i <= n ;i++)
    22     {
    23         
    24             if(maxn<=vis[a[i]])
    25             {
    26                 maxn = vis[a[i]];          //找出出现最多次数的元素;
    27                 flag = a[i];             //记下该元素;
    28                 num = i;                 //并记下它的下标(这里是相同元素的最后一个);
    29             }
    30         
    31     }
    32     
    33     for(int i = num-1 ; i >= 1; i--)
    34     {
    35         if(a[i]==flag)
    36         continue;
    37         else
    38             count1++;                   //计算一共要修改几次;只要不相等就修改;这是往左边的;
    39     }
    40     for(int i = num + 1;i <= n ;i++)
    41     {
    42         if(a[i]==flag)
    43         continue;
    44         else
    45         count1++;              //计算一共要修改几次;只要不相等就修改;这是往右边的;
    46     }
    47     cout<<count1<<endl;
    48     if(count1!=0)               //当有元素需要修改;
    49     {
    50             for(int i = num-1 ; i >= 1; i--)        //往其左边;
    51         {
    52             if(a[i]==flag)              
    53             continue;
    54         
    55                 
    56             else
    57             if(a[i]>flag)                           //如果该元素比它大,则用操作二;且输出的序号为i和i+1;(就是往flag的序号靠);
    58             {
    59                 cout<<2<<" "<<i<<" "<<i+1<<endl;          
    60             }
    61             else
    62             if(a[i]<flag)                       //如果该元素比它小,则用操作一;且输出的序号为i和i+1;(就是往flag的序号靠)
    63             {
    64                 cout<<1<<" "<<i<<" "<<i+1<<endl;
    65             }
    66     }
    67         for(int i = num ;i <= n ;i++)         //往右边;
    68         {
    69             if(a[i]==flag)
    70             {
    71                 continue;
    72             }else
    73             if(a[i]>flag)                  //如果该元素比它大,则用操作二;且输出的序号为i和i-1;(就是往flag的序号靠);
    74             {
    75                 cout<<2<<" "<<i<<" "<<i-1<<endl;
    76             }
    77             else
    78             if(a[i]<flag)
    79             {
    80                 cout<<1<<" "<<i<<" "<<i-1<<endl;      //如果该元素比它小,则用操作一;且输出的序号为i和i-1;(就是往flag的序号靠);
    81             }
    82         }
    83              
    84         
    85         
    86     }
    87     
    88     return 0;
    89 }
  • 相关阅读:
    新组件或功能怎么依附到已有的架构上
    高内聚、低耦合
    软件质量的定义
    软件架构与组件
    架构设计之拥抱着变化而设计(部分讲义分享)
    组件设计原则之概念篇(四)
    抽象类(接口类)的作用
    类,抽象基类,接口类三者间的区别与联系(C++)
    软件的可变性
    软件设计的复杂度
  • 原文地址:https://www.cnblogs.com/yewanting/p/10639030.html
Copyright © 2020-2023  润新知