2021牛客寒假算法基础集训营1 B,I(构造)

题目链接: B 括号I 限制不互素对的排列

B-括号

题目大意

  • 构造一个非空括号字符串,使得“()”子序列的个数是n
  • 串的长度不超过1e5

思路

  • 同样的长度10,5*5 > 4 * 6, 平方的大,所以从根号n入手
  • 先输出根号n个左括号,然后又有d1 = n / 根号n 个右括号,还剩下d2 = n % 根号n 对括号匹配,那么就在右括号倒数第d2个右括号左边插入一个左括号就完事了。

ac代码  

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
    int k; cin >> k;
    if(k == 0){
        cout << ")(" << endl;
        return 0;
    }
    string a;
    int d = sqrt(k); k -= d * d;
    for(int i = 1; i <= d; i ++) a += "(";
    for(int i = 1; i <= d; i ++) a += ")";
    int d1 = k / d, d2 = k % d;
    for(int i = 1; i <= d1; i ++) a += ")";
    for(int i = 0; i < a.size(); i ++){
        if(a.size() - i == d2) cout << "(";
        cout << a[i];
    }
    return 0;
}

I-限制不互素对的排列

题目大意

  • 构造一个n的全排列,使得这个序列中刚好有k个相邻对,两个数不互质,可以输出任意,如果不可以输出-1。
  • 范围:2≤n≤1e5,0≤k≤n/2

思路

  • 有n/2个偶数,偶数之间都不互质,但是偶数扎堆最多只有n/2-1对不互质对,所以分两种情况
  1. k==n/2的时候,那么找一个偶数奇数与某个偶数不互质的,这里找了3和6配。那么开头就是3642,然后输出剩下的所有偶数8 10 12...,紧接着就是所有奇数1 3 5...
  2. k < n / 2的时候,如果n是奇数,先输出n,然后从大到小输出k + 1个偶数,第k+1个偶数是ai,然后从ai+1开始输出k+1个奇数,最后剩下的数从一开始输出完1 2 3...
  • 比如12 2->12 10 8 | 7 9 11 | 1 2 3 4 5 6 (三部分) , 11 3->11 | 10 8 6 4 | 3 5 7 9 | 1 2 (四部分),  10 5->3 | 6 4 2 8 10 | 1 5 7 9(三部分)
  • 由于1与任何数都互质,所以说(2 1), (3 1), (4 2), (5 2)这些都不存在

ac代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<int> ans;
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    if((n==4||n==5)&&m==2){
        puts("-1");
        return 0;
    }
    if((n == 2 || n == 3 ) && m == 1){
        puts("-1");
        return 0;
    }
    if(m < n / 2){
        if(n & 1) ans.push_back(n);
        int st = n / 2 * 2; //最大的偶数
        for(int i = 0; i <= m; i ++){ //m+1个偶数,m对不互质
            ans.push_back(st);
            st -= 2;
        }
        st ++; //m+1个奇数,与上面偶数对应,相差1
        for(int i = 0; i <= m; i ++){
            ans.push_back(st);
            st += 2;
        }
        int dd = n - (m + 1) * 2; //剩下的数
        if(n & 1) dd --; //如果n是奇数,开头输出n,那么剩下的数-1
        for(int i = 1; i <= dd; i ++){
            ans.push_back(i);
        }
    }else{
        ans.push_back(3);
        ans.push_back(6);
        ans.push_back(4);
        ans.push_back(2);
        for(int i = 8; i <= n; i += 2) ans.push_back(i);
        for(int i = 1; i <= n; i += 2){
            if(i == 3) continue; //之前输出过
            ans.push_back(i);
        }
    }
    for(int i = 0; i < ans.size(); i ++){
        if(i) cout << " ";
        cout << ans[i];
    }
    cout << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/113531506