返回顶部

Codeforces Round #550 (Div. 3) D. Equalize Them All (贪心,模拟)

  • 题意:有一组数,可以选择某个数\(a_i\)相邻的一个数\(a_j\),然后可以让\(a_i\)加上或者减去\(|a_i-a_j|\),问最少操作多少次使得数组中所有数相同.

  • 题解:不难发现,每次操作必然可以使得一个数等于它旁边的任意一个数,所以让数组中的其他数等于出现次数最多的那个数一定是最优的,然后我们就去找与那个数相邻的数去求块,正着反着模拟输出一下就可以了,具体看代码吧.

  • 代码:

    int n;
    int a[N];
    map<int,int> mp;
    int mx,res;
    bool st[N];
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>n;
        rep(i,1,n){
        	cin>>a[i];
        	mp[a[i]]++;
        	if(mp[a[i]]>mx){
        		mx=mp[a[i]];
        		res=a[i];
        	}
        }
    
        int i=1;
        cout<<n-mx<<'\n';
    
        while(i<=n){
        	bool flag=false;
        	if(a[i]!=res && a[i-1]==res){
        		while(a[i]!=res && i<=n){
        			int t=1;
        			if(a[i]>res) t=2;
        			cout<<t<<' '<<i<<' '<<i-1<<'\n';
        			st[i]=true;
        			i++;
        			flag=true;
        		}
        	}
        	if(!flag) i++;
        }
        i=n-1;
    
        while(i>=1){
        	bool flag=false;
        	if(a[i]!=res && a[i+1]==res){
        		while(a[i]!=res && i>=1 && !st[i]){
        			int t=1;
        			if(a[i]>res) t=2;
        			cout<<t<<' '<<i<<' '<<i+1<<'\n';
        			i--;
        			flag=true;
        		}
        	}
        	if(!flag) i--;
        }
    
        return 0;
    }
    
posted @ 2020-11-13 09:31  Rayotaku  阅读(63)  评论(0编辑  收藏  举报