1. 程式人生 > >560 div3 E. Minimum Array *

560 div3 E. Minimum Array *

scan auto ans () epp txt src ostream def

  題意:給出兩個長度為n數字串 ab 數字範圍為0-n-1

可以任意改變b 的位置 求

(ai+bi)%n的字典序最小

壓4ms過的。。。

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define
RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f const int N=2e5+5; const int M=1000; int a[N],b[N]; vector<int>table; int cnt[N]; vector<int>ans;
int main() { int n;RI(n); rep(i,1,n) RI(a[i]); rep(i,1,n) RI(b[i]),cnt[b[i]]++; rep(i,0,n-1) if(cnt[i])table.pb(i); vector<int>::iterator it; rep(i,1,n) { int minn=table[0],minn2; it=lower_bound(table.begin(),table.end(),n-a[i]);
if(it==table.end()) { ans.push_back( (a[i]+minn)%n); if(--cnt[minn]==0)table.erase(table.begin()); } else { if( (a[i]+minn)%n<(a[i]+*it)%n ) { ans.push_back( (a[i]+minn)%n); if(--cnt[minn]==0)table.erase(table.begin()); } else { ans.push_back((a[i]+*it)%n); if(--cnt[*it]==0)table.erase(it); } } } rep(i,0,n-1) { if(i!=0)cout<<" "; cout<<ans[i]; } return 0; }
View Code

大神的並查集

技術分享圖片
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long LL;

const int MAX_N=2e5+5;
int n,m,T;
int a[MAX_N],b[MAX_N];
vector<int> ive;
int id[MAX_N];
int res[MAX_N];

int Find(int x){
    if(id[x]!=x)    id[x]=Find(id[x]);
    return id[x]; 
}
Union(int a,int b){
    id[Find(a)]=Find(b);
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;++i)
        scanf("%d",&a[i]);
    int x;
    for(int i=0;i<n;++i)
    {
        scanf("%d",&x);
        ++b[x];    id[i]=i;
    }
    id[n]=0;
    for(int i=0;i<n;++i)
        if(!b[i])    Union(i,i+1);
    for(int i=0;i<n;++i)
    {
        x=Find(n-a[i]);
        res[i]=(a[i]+x)%n;
        --b[x];
        if(!b[x])    Union(x,x+1);
    }
    for(int i=0;i<n-1;++i)
        printf("%d ",res[i]);
    printf("%d\n",res[n-1]);
    
    return 0;
}
View Code

官方題解:

用了重集set

技術分享圖片
#include <bits/stdc++.h>

using namespace std;

int main() {
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    
    int n;
    cin >> n;
    vector<int> a(n);
    multiset<int> b;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < n; ++i) {
        int x;
        cin >> x;
        b.insert(x);
    }
    
    for (int i = 0; i < n; ++i) {
        auto it = b.lower_bound(n - a[i]);
        if (it == b.end()) it = b.begin();
        cout << (a[i] + *it) % n << " ";
        b.erase(it);
    }
    cout << endl;
    
    return 0;
}
View Code

560 div3 E. Minimum Array *