Codeforces Round #555 (Div. 3) E. Minimum Array (貪心,二分,set)
阿新 • • 發佈:2020-11-18
-
題意:給你兩個長度為\(n\)的陣列\(a\)和\(b\),元素值在\([0,n-1]\),可以對\(b\)陣列的元素任意排序,求新陣列\(c\),滿足\(c_i=(a_i+b_i)\ mod\ n\),並且使得其字典序最小.
-
題解:這種取模求最小的題,我們一眼就能看出最優情況一定是\(b_i=n-a_i\),可以先用set存一下\(b\)中的元素,然後在set中二分找\(\ge \ n-a_i\)的值,因為\(a_i\)加上一個比\(n-a_i\)小的數再取模一定\(\ge a_i\),但是加上\([n-a_i,n-1]\)中的數一定再取模的範圍在\([0,a_i-1]\),因為加上\(n-a_i\)
-
程式碼:
int n; int a[N]; int x; set<int> s; map<int,int> mp; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n; rep(i,1,n) cin>>a[i]; rep(i,1,n){ cin>>x; mp[x]++; s.insert(x); } s.insert(n); rep(i,1,n){ if(a[i]==0) a[i]=n; auto cur=s.lower_bound(n-a[i]); if(*cur==n){ int now=*s.begin(); cout<<(now+a[i])%n<<' '; mp[now]--; if(mp[now]==0) s.erase(now); continue; } cout<<(*cur+a[i])%n<<' '; mp[*cur]--; if(mp[*cur]==0) s.erase(*cur); } return 0; }