Codeforces Round 1024 (Div. 2)(A-D)

题面链接:Dashboard - Codeforces Round 1024 (Div. 2) - Codeforces

A. Dinner Time

思路

一共n个数被分成n/p个区间,每个区间内的和是q,如果还有除构成区间外剩余的数那么就一定能构造,如果没有剩余就看所有区间的和是否等于m

代码

cpp 复制代码
void solve(){
    int n,m,p,q;
    cin>>n>>m>>p>>q;
    int t=n/p;
    int res=n%p;
    if(res==0){
        if(t*q!=m){
            cout<<"No\n";
        }else{
            cout<<"Yes\n";
        }
    }else{
        cout<<"Yes\n";
    }
}

B. The Picky Cat

思路

我们统计绝对值大于x的数,如果大于的数过半就可以,我们可以将绝对值大于x的数取负那么原本比x大的数就会比x小

代码

cpp 复制代码
void solve(){
    int n;
    cin>>n;
    vector<int> a(n+10);
    int cnt=0;  //记录绝对值大于a[1]的数量
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    int x=abs(a[1]);
    for(int i=1;i<=n;i++){
        if(abs(a[i])>=x) cnt++;
    }
    if(cnt>=(n+1)/2){
        cout<<"Yes\n";
    }else{
        cout<<"No\n";
    }
}

C. Mex in the Grid

思路

这题得贪心地构造,我们要子网格地mex尽可能大,我们就要求对于每个网格尽可能的包含0 1 2...

我们很容易看出我们要把0放在网格的中间,之后填数的时候我们以0为起点螺旋的构造

这样就可以贪心的保证子网格mex的和最大

代码

cpp 复制代码
void solve() {
    int n;
    cin >> n;
    vector<vector<int>> g(n, vector<int>(n, -1));
    int dir[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};
    int x = n/2, y = n/2;
    if (n % 2 == 0) { x--; y--; }
    int num = 0;
    g[x][y] = num++;
    int d = 0;
    int st = 1;
    bool f = false;

    while (num < n * n) {
        for (int k = 0; k < 2; ++k) {
            for (int i = 0; i < st; i++) {
                x += dir[d][0];
                y += dir[d][1];
                if (x < 0 || x >= n || y < 0 || y >= n) continue;
                if (g[x][y] == -1) {
                    g[x][y] = num++;
                }
            }
            d = (d + 1) % 4;
        }
        st++;
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cout << g[i][j] << " ";
        }
        cout << "\n";
    }
}

D. Quartet Swapping

思路

关于此题我们观察出奇数和偶数要分成两组,我们在进行操作的时候偶数组和奇数组是不会相互交换的,也就是在最终答案统计的时候每个位置的数奇偶性是不会改变的

假设现在有一个数组,分为奇偶

1 2 3 4 5 6 7 8

现在我们将5移动到1的位置我们可以先后交换 先选择i=2 : 5->3 i=1 : 5->1

那么数组就会变为 5 2 1 4 3 6 7 8,这时候我们发现我们将5前移了两位,而偶数组的数并未发生改变,但是考虑我们如果只前移一位的时候我们便会交换偶数组的两个数,那么我们怎么处理才能够使得偶数组的数未发生改变,我们只需要将移动后的最后两个数交换即可

那么我们先假设最后的两个数没有交换贪心地移动偶数组和奇数组的数,最后在根据奇数组和偶数组最后有没有交换更新答案即可,那么到底移动了多少次呢?

我们回到问题的要求,需要尽可能的将小数排序,我们可以想到每次将数组小的数放到前面即可,那么就能够想到统计以下逆序对的个数,即移动次数

我们可以用BIT来统计一下偶数组和奇数组的逆序对的个数,如果奇偶性相同的话就不用交换最后的数了,如过不同我们就交换一下ans[n]与ans[n-2]

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;

#define lowbit(x) ((x)&-(x))
struct BIT{
    int n;
    vector<int> tree;
    void init(int x){
        n=x;
        tree.resize(x+10);
    }
    void update(int x,int d){
        for(int i=x;i<=n;i+=lowbit(i)){
            tree[i]+=d;
        }
    }
    int sum(int x){
        int ans=0;
        for(int i=x;i>0;i-=lowbit(i)){
            ans=ans+tree[i];
        }
        return ans;
    }
};

void solve() {
    int n;cin>>n;
    vector<int> a(n+10);
    for(int i=1;i<=n;i++) cin>>a[i];

    vector<int> x,y;
    for(int i=1;i<=n;i++){
        if(i%2) x.push_back(a[i]);
        else y.push_back(a[i]);
    }

    //统计逆序对的数量
    BIT btx;
    btx.init(n);
    int sx=0;
    for(int i=x.size()-1;i>=0;i--){
        sx+=btx.sum(x[i]);
        btx.update(x[i],1);
    }
    BIT bty;
    bty.init(n);
    int sy=0;
    for(int i=y.size()-1;i>=0;i--){
        sx+=bty.sum(y[i]);
        bty.update(y[i],1);
    }

    
    sort(x.begin(),x.end());
    sort(y.begin(),y.end());
    vi ans(1);
    for(int i=1;i<=n;i++){
        if(i%2) ans.push_back(x[i/2]);
        else ans.push_back(y[(i/2)-1]);
    }
    if((sx%2)!=(sy%2)) swap(ans[n],ans[n-2]);

    for(int i=1;i<=n;i++){
        cout<<ans[i]<<" ";
    }cout<<"\n";


}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    int _=1;
    cin>>_;
    while(_--) solve();
    return 0;
}
相关推荐
W23035765738 小时前
经典算法:最长上升子序列(LIS)深度解析 C++ 实现
开发语言·c++·算法
.Ashy.8 小时前
2026.4.11 蓝桥杯软件类C/C++ G组山东省赛 小记
c语言·c++·蓝桥杯
2401_892070988 小时前
链栈(链式栈) 超详细实现(C 语言 + 逐行精讲)
c语言·数据结构·链栈
minji...9 小时前
Linux 线程同步与互斥(三) 生产者消费者模型,基于阻塞队列的生产者消费者模型的代码实现
linux·运维·服务器·开发语言·网络·c++·算法
语戚10 小时前
力扣 968. 监控二叉树 —— 贪心 & 树形 DP 双解法递归 + 非递归全解(Java 实现)
java·算法·leetcode·贪心算法·动态规划·力扣·
skywalker_1110 小时前
力扣hot100-7(接雨水),8(无重复字符的最长子串)
算法·leetcode·职场和发展
bIo7lyA8v11 小时前
算法稳定性分析中的输入扰动建模的技术9
算法
CoderCodingNo11 小时前
【GESP】C++三级真题 luogu-B4499, [GESP202603 三级] 二进制回文串
数据结构·c++·算法
sinat_2869451911 小时前
AI Coding 时代的 TDD:从理念到工程落地
人工智能·深度学习·算法·tdd