Codeforces Round #758 (Div.1 + Div. 2) 题解

296 阅读2分钟

A. Find Array (签到)

image.png

题意:输入一个n,输出n个数,要求ai不被ai-1整除。
题解:很容易发现从2开始ai不可能被ai-1整除。所以直接输出2~n+1。

void solve()
{
    cin >> n;
    rep(i,2,n+1) cout<<i<<" ";
    cout<<endl;
}

B. Build the Permutation(构造)

image.png

题意:输入一个n,a,b。表示输出n个数构成n的序列,要求a个山峰b个山谷。山峰指 ai-1<ai>ai+1 ,山谷指ai-1>ai<ai+1,如果不能构成输出-1。
题解:感觉属于比较难的B了..首先来判断不能构成的情况,由于一个序列能最多能够构成的是a+b<=n-2(去掉收尾),再考虑由于两个山峰之间有一个山谷,那么a和b的差值允许的是1,可以证明,当山峰-山谷-山峰以后如果再想构造出一个山峰是不可能的,后面不想构造除山谷的话肯定只能够降序,那么在想构造出山峰,山峰前面必然产生一个山谷。
最后就是怎么构造出符合条件的,首先可以输出n-(a+b)-1个数,因为构造出a+b个山峰山谷用不到这些,剩下的数字,很容易想到n=6的话可以162534这样穿插的构造,这样构造的好处在于只要是有一段连续的值都可以像这样构造出来。这样构造完是a==b和a>b的情况,那么a<b实际上就是每个数求一个n-a[i]+1的映射。

void solve()
{
    int A,B;
    cin >> n >> A >> B;
    if(A+B+2>n || abs(A-B)>1)ot(-1)
    int t=n-(A+B)-1;
    rep(i,1,t) a[i]=i;
    int l=t+1,r=n;
    int ok=1;
    rep(i,t+1,n)
    {
        if(ok==-1) a[i]=l++;
        else a[i]=r--;
        ok*=-1;
    }
    if(A<B)
    {
        rep(i,1,n) a[i]=n-a[i]+1;
    }
    rep(i,1,n) cout<<a[i]<<" ";
    cout<<endl;

}

C. Game Master

image.png

题意:输入一个n,随即两行n个整数,表示n个玩家在两张图的能力值,求玩家是否能够胜利的序列
题解:可以发现的是,答案是和在玩家在两张图上的排位决定的,所以我们先对数组排序出两个图上的排名。然后遍历n即可,具体看代码。

void solve()
{
    cin >> n;
    vector<int> A(n),B(n),a(n),b(n);
    rep(i,0,n-1) cin >> A[i];
    rep(i,0,n-1) cin >> B[i];
    rep(i,0,n-1) a[i]=b[i]=i;
    sort(a.begin(),a.end(),[&](int x,int y){return A[x]>A[y];});
    sort(b.begin(),b.end(),[&](int x,int y){return B[x]>B[y];});
    vector<int> v(n,0);
    set<int> st;
    string ans(n,'0');
    rep(i,0,n-1)
    {
        v[a[i]]++;
        v[b[i]]--;
        if(v[a[i]]) st.insert(a[i]);
        if(v[b[i]]) st.insert(b[i]);
        if(!v[a[i]]) st.erase(a[i]);
        if(!v[b[i]]) st.erase(b[i]);
        if(st.empty())
        {
            rep(j,0,i) ans[a[j]]='1';
            break;
        }
    }
    cout<<ans<<endl;
}