2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ABC414個人的備忘録[A-D(E)]

Last updated at Posted at 2025-07-12

何も見えなくなった男の備忘録です

コンテスト概要

ミラティブ プログラミングコンテスト2025(AtCoder Beginner Contest 414

開催日:2025年7月12日 21:00-22:40

A - Streamer Takahashi

考察

視聴者全員に活動時間があるので、それぞれの活動時間中に配信が行われるのは何人か?ということ。

ifを使って簡便に

提出

A.cpp
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n,l,r;
    cin >> n >> l >> r;

    int ans = 0;
    for(int i=0;i<n;i++){
        int x,y;
        cin >> x >> y;

        if(x <= l && r <= y) ans++;
        //配信時間が活動時間に完全に含まれるならカウントを増やす
    }

    cout << ans << endl;
}

B - String Too Long

考察

前回の復習って感じ。
とりあえず長さの制限を無視すれば、ポンポンqueueに入れて復元するだけ。
復元はforを使えば簡単。

あとは長すぎるときの判断をしたい。
シンプルに長さを足すとオーバーフローする。
なので
〇そもそも文字数が100を超えてたらX。
〇100以下なら足して、合計が100超えたらX
というように明らかにダメなやつをはじいておく。

提出

B.cpp
#include <bits/stdc++.h>
using namespace std;

int main(){
    ll n;
    cin >> n;

    vector<pair<char,ll>>num (n);
    bool che = false;
    ll sum = 0;

    for(int i=0;i<n;i++){
        cin >> num[i].first >> num[i].second;

        if(num[i].second > 100LL) che = true;//デカすぎるならはじく
        else sum += num[i].second;//小さいものをチェック
    }

    if(sum > 100 || che) cout << "Too Long";//結局100を超えたらはじく
    else{
        for(int i=0;i<n;i++){
            auto[c,x] = num[i];
            for(int j=0;j<x;j++) cout << c;
            //forを使って復元
        }
    }
    cout << endl;    
}

C - Palindromic in Both Bases

考察

ボロボロにされました。
とりあえず10進数の回文数を考える。前半分を決めれば後ろも決まる。なので$10^7$個試せばOK。
なので、回文数は最大でも$2\times10^7$個なので何とかなる。

後はそれら全部にA進数の時に回文になってるかを試せば...TLE。
これの時間短縮を頑張ったが60分が無駄に。

10進で$10^7$個、だったらA進数でも$10^7$個ぐらい。
後は簡単A進数でも全部確認すればよい。

さっさとやればよかったね。

(7/14追記)
とんでもない勘違いをしていました。
これ$10^7$じゃなくて$10^6$で十分です。
$10^6$なら回文になっているか試しても余裕で間に合います。
「1e7」を「1e6」に変えるだけでACできました。

提出

6を7に変えたほう
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

bool check(ll n,ll m){
    string s = "";//A進数を文字列に変換
    while(n != 0){
        char x = '0' + (n%m);
        s += x;
        n /= m;
    }

    string t = s;
    reverse(s.begin(),s.end());//片方をひっくり返す

    if(s == t) return true;//同じかを判定。
    return false;
}

int main(){
    ll a,n;
    cin >> a >> n;
    set<ll> st;

    ll lim = 1e6;//最大値は10^6乗で十分。
    for(int i=1;i<lim;i++){
        ll m = i;
        vector<ll>num (0);//数字をそれぞれ受け取る。
        while(m != 0){
            num.push_back(m%10LL);
            m /= 10LL;
        }

        ll x=i,y=i;
        x *= 10LL;
        x += num[0];
        //xは完全な折り返し。yは中心が1つの回文

        for(int j=1;j<num.size();j++){
            x *= 10LL;
            y *= 10LL;
            x += num[j];
            y += num[j];
        }

        if(check(x,a)) st.insert(x);
        if(check(y,a)) st.insert(y);
    }

    ll ans = 0;
    //setで管理しているがそもそもその場で確認したほうがスマート。
    for(auto x:st){
        if(x > n) break;
        ans += x;
    }

    cout << ans << endl;    
}
コンテスト中に提出したごちゃごちゃしたほう
C.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;


int main(){
    ll a,n;
    cin >> a >> n;

    ll ans = 0;
    map<ll,bool>mp;
    ll lim = (1<<21);//2進数の最大を考えておく

    //10進数の回文を求める。
    for(int i=1;i<lim;i++){
        ll m = i;
        vector<ll>num (0);
        while(m != 0){
            num.push_back(m%10LL);
            m /= 10LL;
        }
        //前半分を決めたら折り返しに注意して2パターン作る
        ll x=i,y=i;
        x *= 10LL;
        x += num[0];

        //値をどんどん後ろに追加
        for(int j=1;j<num.size();j++){
            x *= 10LL;
            y *= 10LL;
            x += num[j];
            y += num[j];
        }

        //できたやつをmapに入れておく
        if(x <= n) mp[x] = true;
        if(y <= n) mp[y] = true;
    }

    //A進数でも同じようにやる
    for(int i=1;i<lim;i++){
        ll m = i;
        vector<ll>num (0);
        while(m != 0){
            num.push_back(m%a);
            m /= a;
        }
        
        //折り返しに注意して2パターン
        ll x=i,y=i;
        x *= a;
        x += num[0];

        //値をどんどん後ろに追加
        for(int j=1;j<num.size();j++){
            x *= a;
            y *= a;
            x += num[j];
            y += num[j];
        }

        if(mp[x]) ans += x;
        if(mp[y]) ans += y;
    }

    cout << ans << endl;    
}

D - Transmission Mission

考察

一旦C問題を飛ばしてDをやる。
二分探査を考えるが上手くいかず、撤退。

ボロボロになりながらD問題にたどり着く。

よくよく考えたら近い家をまとめたほうがいい。
なので近くの家をどんどん併合すればおしまい。

5分でAC。冷静さが欲しい。

提出

D.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<typename T> using p_que = priority_queue <T,vector<T>,greater<T>>;


int main(){
    ll n,m;
    cin >> n >> m;

    vector<ll> num (n);
    for(int i=0;i<n;i++) cin >> num[i];

    sort(num.begin(),num.end());//家を西から並べておく

    p_que<ll>que;
    for(int i=1;i<n;i++) que.push(num[i] - num[i-1]);//隣接する家ごとの距離を出す。
    m = n-m;//足りない分だけ家を併合する。

    ll ans = 0;
    while(m != 0){
        m--;
        ans += que.top();
        //家の距離を払い家同士を併合。
        que.pop();
    }

    cout << ans << endl;    
}

E - Count A%B=C

考察

残り2分。グデグデしながら考えたら解法が思いついて絶望。

一旦条件は無視。
とりあえずBを中心に考えると。すべてのAに対して1つのCが決まるので全部で$N^2$通りある。ここから条件を加味する。

B以下のAはA=Cになるので省く。
AがBで割り切れるとき、C=0なので省く。

この2つを考えればOK。
AがB以下になるのは$\frac{(N+1)\times N}{2}$個
c=0になるのは$\sum_{K=1}^N \lbrack \frac{N}{K} \rbrack$個(中身はガウス記号)

この二つを重複に気を付けて引けばよかったんですね。

提出

E.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll mod = 998244353LL;

int main(){
    ll n;
    cin >> n;

    //n^2を計算
    ll ans = n;
    ans %= mod;
    ans *= ans;
    ans %= mod;

   //1~Nまでの総和を計算。
    ll sum = 0;
    ll a = n,b = n+1LL;
    if(a%2 == 0) a/=2LL;
    else b/=2LL;
    a %= mod,b %= mod;
    sum = a*b;
    sum %= mod;

    ans = mod+ans-sum;
    ans %= mod;

    //N/Kの値を求める
    ll now = 1LL;
    while(n/now != 1){
        ll x = n/now;
        ll y = n/x +1LL;

        x = (x-1LL)%mod;//かぶりを消すため1減らす。
        ll z = (y-now) % mod;
        now = y;
        z *= x;
        z %= mod;

        ans = mod+ans - z;   
        ans %= mod;     
    }

    cout << ans << endl;    
}

結果

ABC(1)D(1) 4完 107:15

順位 3143位
パフォーマンス 979
レート 1353(-35)

感想

完全に冷静さを欠きました。

深呼吸すれば何とかなっただろうか?
今後は冷静に行きます。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?