接着剤の精進日記

競プロでの精進や研究に関係したことを書いていきます。

AtCoder Beginner Contest 207(ABC207)

atcoder.jp

A - Repression

選び方は三通りなので、その中の最大を出力
提出コード

void solve(){
    int A, B, C;
    cin >> A >> B >> C;
    cout << max({A+B, B+C, A+C}) << endl;
}

B - Hydrate

必要な操作の最小値が $ A $ 程度となるので、愚直にループで条件を満たすか確認する
提出コード

void solve(){
    ll A, B, C, D;
    cin >> A >> B >> C >> D;
    REP(i,101010){
        if(A + B*i <= C*i*D){
            cout << i << endl;
            return;
        }
    }
    cout << -1 << endl;
}

C - Swappable

$ [l_i, r_i] $ を $ [l_i, r_i] $
$ [l_i, r_i)$ を $ [l_i, r_i + 0.5] $
$ (l_i, r_i] $ を $ [l_i - 0.5, r_i] $
$ (l_i, r_i) $ を $ [l_i - 0.5, r_i + 0.5] $ として扱う
上記のように考えた区間上で共通部分を持つものを全探索をする
提出コード

void solve(){
    int N;
    cin >> N;
    vector<ll> l(N), r(N);
    REP(i,N){
        int t;
        cin >> t >> l[i] >> r[i];
        l[i] *= INF;
        r[i] *= INF;
        if(t == 2) r[i]--;
        if(t == 3) l[i]++;
        if(t == 4) l[i]++, r[i]--;
    }
    int ans = 0;
    REP(i,N) for(int j=i+1;j<N;j++){
        ll L = max(l[i], l[j]);
        ll R = min(r[i], r[j]);
        if(L <= R) ans++;
    }
    cout << ans << endl;
}

D - Congruence Points

$ S, T $ をそれぞれの重心を原点に平行移動させて考える
そうすると、それぞれ回転移動のみを考えればいい
$ S $ のある頂点 $ (a_0, b_0) $ に対応する $ T $ の頂点を $ (c_i, d_i) $ とする
そうすると $ (a_j, b_j) $ を回転させたときの点に対応する頂点 $ (c_k, d_k) $ がすべての頂点について存在すればいい
よって上記を全探索をすればいい
提出コード

template <typename float_type>
bool EQ(float_type a, float_type b) { return abs(a - b) < EPS; }
 
void solve(){
    int N;
    cin >> N;
    vector<double> a(N), b(N), c(N), d(N);
    int sx = 0, sy = 0;
    int tx = 0, ty = 0;
    REP(i,N){
        cin >> a[i] >> b[i];
        sx += a[i];
        sy += b[i];
        a[i] *= N;
        b[i] *= N;
    }
    REP(i,N){
        cin >>  c[i] >> d[i];
        tx += c[i];
        ty += d[i];
        c[i] *= N;
        d[i] *= N;
    }
    REP(i,N){
        a[i] -= sx;
        b[i] -= sy;
        c[i] -= tx;
        d[i] -= ty;
    }
    REP(i,N) if(a[i] != 0 || b[i] != 0){
        swap(a[0], a[i]);
        swap(b[0], b[i]);
    }
 
    REP(i,N){
        double arg = atan2(d[i], c[i]) - atan2(b[0], a[0]);
        bool ok = true;
        REP(j,N){
            double x = a[j] * cos(arg) - b[j] * sin(arg);
            double y = a[j] * sin(arg) + b[j] * cos(arg);
            bool ok2 = false;
            REP(k,N){
                if(EQ(x, c[k]) and EQ(y, d[k])) ok2 |= true;
            }
            ok &= ok2;
        }
        if(ok){
            cout << "Yes" << endl;
            return;
        }
    }
    cout << "No" << endl;
}