(Aleppo + HAIST + SVU + Private) CPC 2022

D

Dashboard - (Aleppo + HAIST + SVU + Private) CPC 2022 - Codeforces

题意:给一个n,数组A为1~n,数组B为2~n+1,交换若干次对应位置的数,使A乘积等于B乘积

思路:28b34055d8fe41b0b06884e3c0d6da4b.jpeg

 

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int , int>
const int N = 1e6 + 10;
const int mod = 1e9 + 7, inf = 0x3f3f3f3f;
int n, m;
int a[N], b[N], vis[N];

void init(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout. tie(0);
}

signed main()
{
    init();

    map<int, int> mp;
    for(int i = 1; i <= 1000; i ++) mp[i * i] = i;
    int q;
    cin >> q;
    while(q --){
        int n;
        cin >> n;
        n += 1;
        if(mp.count(n)){//是完全平方数
            cout << sqrt(n) - 1 << endl;
            for(int i = 1; i <= sqrt(n) - 1; i ++)
                cout << i << ' ';
            cout << endl;
        }
        else cout << -1 << endl;
    }
    return 0;
}

 

L

题意:给一个序列,找出连续奇数(偶数)个数不超过k个的子序列,且子序列元素和尽可能大

思路:将连续的奇数(偶数)放入优先队列,取出前k个

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int , int>
const int N = 1e6 + 10;
const int mod = 1e9 + 7, inf = 0x3f3f3f3f;
int a[N], b[N], vis[N];

void init(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
}

signed main()
{
    init();

    int TT;
    cin >> TT;
    while(TT --)
    {
        int n, k, ans = 0;
        cin >> n >> k;
        priority_queue<int> q;
        for(int i = 0; i < n; i ++){
            cin >> a[i];
            if(i != 0 && (a[i] - a[i - 1]) % 2){//不同
                int cnt = 0;
                while(q.size()){
                    int t = q.top();
                    if(cnt < k){
                        ans += t;
                        cnt ++;
                    }
                    q.pop();
                }
            }
            q.push(a[i]);
        }

        int cnt = 0;
        while(q.size()){
            int t = q.top();
            if(cnt < k){
                ans += t;
                cnt ++;
            }
            q.pop();
        }
        cout << ans << endl;
    }
    return 0;
}

 

M

题意:长度为n的全排列中,有多少对合法对,合法对:后一个数能被前一个数整除(eg:n为3,一种排列为1 2 3,12、13两对合法,其他排列2 1 3,13一对合法)

思路:x,y (x!=y), 在全排列中以x,y和y, x先后顺序出现的情况各有一半(eg:3的6种全排列中,1在前,2在后出现三次,反之出现三次),所以一对合法对的贡献为 全排列数/2,答案就是合法对数量乘一对的贡献,所以预处理出合法对的数量

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10, mod = 1000000007;
int hf[N], shf[N], pai[N];


void init(){
    for(int i = 1; i <= N; i ++){
        for(int j = 2; i * j <= N; j ++){
            hf[i * j] ++; //合法情况
        }
    }

    for(int i = 1; i <= N; i ++){ //合法总数
        shf[i] = (shf[i - 1] + hf[i]) % mod;
    }

    pai[2] = 1;//2的全排列设为1,所有的就已经除以2了
    for(int i = 3; i <= N; i ++){//全排列
        pai[i] = pai[i - 1] * i % mod;
    }
}

signed main()
{
    init();

    int q;
    cin >> q;
    while(q --)
    {
        int n;
        cin >> n;
        int p = pai[n];
        int ans = ((shf[n] % mod) * (p % mod)) % mod;
        cout << ans << endl;
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值