思路:模拟。在x前面找到最小值,如果没有,从0跳到n,继续找到最小值,边找最小值路过的点边减1。然后所有值都减去最小值,最小值那个点加上减去的值。
找到x前面离x最近的最小值的原因:如果如果在x到最小值之间还有最小值,那么这个最小值最后会变成-1。
简单代码:
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+5; const ll INF=0x7f7f7f7f; ll a[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); ll n,x,minn=INF; cin>>n>>x; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) { minn=min(minn,a[i]); } ll sum=0; while(a[x]!=minn) { a[x]--; sum++; x--; if(x==0)x=n; } for(int i=1;i<=n;i++) { if(i!=x)cout<<a[i]-minn; else cout<<a[i]+sum+(n-1)*minn; if(i!=n)cout<<' '; else cout<<endl; } return 0; }
复杂点的代码(找最小值时没有减1):
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+5; const ll INF=0x7f7f7f7f; ll a[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); ll n,x,minn=INF,d=INF,index=-1; cin>>n>>x; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) { if(a[i]<=minn) { minn=a[i]; index=i; } } bool flag=true; for(int i=x;i>=1;i--) { if(a[i]==minn) { index=i; flag=false; break; } } if(flag)for(int i=n;i>x;i--) { if(a[i]==minn) { index=i; break; } } ll cnt=0; if(index<x) { cnt=index*minn+(n-x)*minn+(x-index)*(minn+1); for(int i=1;i<=index;i++)a[i]-=minn; for(int i=index+1;i<=x;i++)a[i]-=minn+1; for(int i=x+1;i<=n;i++)a[i]-=minn; a[index]+=cnt; } else if(index>x) { cnt=x*(minn+1)+(n-index)*(minn+1)+(index-x)*minn; for(int i=1;i<=x;i++)a[i]-=minn+1; for(int i=x+1;i<=index;i++)a[i]-=minn; for(int i=index+1;i<=n;i++)a[i]-=minn+1; a[index]+=cnt; } else { cnt=n*minn; for(int i=1;i<=n;i++)a[i]-=minn; a[index]+=cnt; } for(int i=1;i<n;i++)cout<<a[i]<<' '; cout<<a[n]<<endl; return 0; }