【CodeForces训练记录】Codeforces Round 993 (Div. 4)

训练情况

赛后反思

凌晨我又在宿舍制造键盘噪音了,还是div4,声音更大了。E题呆了,看出 log 做法但是不会算答案贡献

A题

\(a+b=n(a,b>0)\)\(1 \sim n-1\)\(n-1\) 对,看样例直接猜 \(n-1\)

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int x; cin>>x;
    cout<<x-1<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

B题

字符串倒过来输出,p变q,q变P

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    string s; cin>>s;
    int n = s.size();
    for(int i = n-1;~i;i--){
        if(s[i] == 'p') cout<<"q";
        else if(s[i] == 'q') cout<<"p";
        else cout<<s[i];
    }
    cout<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

C题

优先排有需求的,需要每排对 \(m\) 取最小值,剩下的无需求的随便放,再对 \(2m\) 取最小值。

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int m,a,b,c;
    cin>>m>>a>>b>>c;
    int ans1 = 0,ans2 = 0;
    ans1 += a;
    ans2 += b;
    ans1 = min(m,ans1);
    ans2 = min(m,ans2);
    cout<<min(2*m,ans1+ans2+c)<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

D题

构造一个数组 \(b\),使得 \(b_1 \sim b_i\) 的众数是 \(a_i\),我们发现众数可以为多个,所以我们只需要构造一个 \(1 \sim n\) 只出现一次的数组,接下来就是保证数字第一次出现的位置有对应的数即可,剩下的随便放。

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int n; cin>>n;
    vector<int> a(n + 1);
    for(int i = 1;i<=n;i++) cin>>a[i];
    vector<int> pos(n + 3),ans(n + 3);
    vector<bool> vis(n + 3);
    for(int i = 1;i<=n;i++) if(!pos[a[i]]) pos[a[i]] = i,ans[i]=a[i],vis[a[i]] = 1;
    int tot = 1;
    for(int i = 1;i<=n;i++){
        if(ans[i]) cout<<ans[i]<<" ";
        else {
            while(vis[tot]) ++tot;
            vis[tot] = 1;
            cout<<tot<<" ";
        }
    }
    cout<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

E题

\(\frac{y}{x} = k^n\),我们可以找 \(\frac{y}{x}\) 的上下界,上界就是分子 \(y\) 尽可能大,分母 \(x\) 尽可能小,为 \(\lfloor \frac{r_2}{l_1} \rfloor\),下界就是分子 \(y\) 尽可能小,分母 \(x\) 尽可能大,为 \(\lceil \frac{l_2}{r_1} \rceil\),接下来就是预处理 \(k^n\),复杂度是 \(O(logk)\) 的,在上下界的范围内进行计数,直接 \(\frac{y}{k^n}\) 找到 \(x\) 的上下界计数即可(记得对 \(l_1,r_1\) 取 max 和 min)。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'

using namespace std;

void solve(){
    int k,l1,r1,l2,r2;
    cin>>k>>l1>>r1>>l2>>r2;
    int l = (l2+r1-1)/r1;
    int r = r2/l1;
    int base = 1;
    int ans = 0;
    // cout<<l<<" "<<r<<endl;
    while(base<l) base*=k;
    while(base<=r){
        int ll = (l2+base-1) / base;
        int rr = r2 / base;
        ll = max(l1,ll);
        rr = min(r1,rr);
        if(ll<=rr) ans += rr-ll+1;
        base*=k;
    }
    cout<<ans<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

G1

观察样例,传递的过程,让我想到了有点类似于拓扑排序,答案是类拓扑排序的次数 + 2,找入度为 \(0\),但是需要队列里面一层一层全部取出来再入队。

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int n; cin>>n;
    vector<int> a(n + 1);
    for(int i = 1;i<=n;i++) cin>>a[i];
    vector<int> edge[n + 1];
    vector<int> cnt(n + 1,0);
    for(int i = 1;i<=n;i++){
        edge[i].push_back(a[i]);
        cnt[a[i]]++;
    }
    queue<int> q;
    for(int i = 1;i<=n;i++) if(!cnt[i]) q.push(i);
    int ans = 0;
    while(q.size()){
        int lim = q.size();
        for(int i = 1;i<=lim;i++){
            int t = q.front(); q.pop();
            for(auto v:edge[t]){
                cnt[v]--;
                if(!cnt[v]) q.push(v);
            }
        }
        ans++;
    }
    cout<<ans+2<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}
posted @   MNNUACM_2024ZY  阅读(379)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示