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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮