教育Codeforcesラウンド70题解

ゲームリンクhttps://codeforc.es/contest/1202
 
A.あなたが与えられていることにより、二つのバイナリ文字列の...
質問の意味:与えられた2つの2進数\(f(x)が\)\(F(Y)\ )、二進数定義\(S_K = F(X)+ 2 ^ K \ CDOT F(Y)\) 要求し\(K \)のどんな値\(S_K \)逆文字列(バイナリ見シリアル番号01)辞書最小。

分析:まず第一に、我々は全体の左1の数に相当する2の2進数のために知っておく必要がありますので、我々はちょうど見つける必要がある\(F(Y)\) 1の右端に位置を(\ POS)\、それ作るために\(F(X)\)の中で\(POS \)左最新(\ \ Y)こうして逆辞書式に最小不可避得一致ストリング。

ACコード

#include <bits/stdc++.h>
#define SIZE 200007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}
ll n, m, t;
string s1, s2;
int main() {
    io(); cin >> t;
    while(t--) {
        cin >> s1 >> s2;
        int len1 = s1.length() - 1, len2 = s2.length() - 1;
        n = 0;
        while(s2[len2--] == '0') ++n;
        m = n;
        while(s1[len1 - m] == '0') ++m;
        cout << m - n << endl;
    }
}

 
B.あなたが十進文字列...与えられている
質問の意味:非常に明確ではありません話す、あなたは理解する上でサンプルの質問を見ることができます。文字列文字列を決意の任意の組み合わせの2つの数の各桁を与え、クエリーは、文字列を取得するために、複数のコンフィギュレーションは、いくつかの無効な番号の最小値を必要とします。例:
文字列指定された\(0840 \)二つの数字について決定を、\((2、4)\)

  1. 0(初期にはゼロでなければなりません)
  2. 04( \(+ 4 \)
  3. 048( \(+ 4 \)
  4. 0482(\ (4 + \) およびのみ10の以上の数字であれば)
  5. 04824( \(+ 2 \)
  6. 048248( \(+ 4 \)
  7. 0482480( \(+ 2 \)

したがって、(0)4(8)2(4)、8(0)、3の数のために生成された番号。

分析:最初の列から\(K \)は、ビットがする\(K + 1 \)ビットが実際の変化に対応する\(。\ K + 1ヴェールS_ {} -s_k \ヴェール\) この値が10を超えません桁数は無効とすることができ、私たちはちょうど発生した暴力の10例を見つける必要があります。

ACコード

#include <bits/stdc++.h>
#define SIZE 200007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
const int maxn = 1e9;
using namespace std;
typedef long long ll;
void io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}
int n, m, t; int dp[10];
string s;
int main() {
    io(); cin >> s;
    int len = s.length();
    rep(i, 0, 9) {
        rep(j, 0, 9) {
            rep(i, 0, 9) dp[i] = maxn;
            rep(x, 0, 9) {
                rep(y, 0, 9) {
                    if (!x && !y) continue;
                    dp[(x * i + y * j) % 10] = min(x + y - 1, dp[(x * i + y * j) % 10]);
                }
            }
            int ans = 0;
            rep(k, 0, len - 2) {
                int tmp = s[k + 1] - s[k];
                if (dp[(tmp + 10) % 10] == maxn) { ans = -1; break; }
                ans += dp[(tmp + 10) % 10];
            }
            cout << ans << ' ';
        }
        cout << endl;
    }
}

 
C.あなたはWASD文字列を与えられている ...
そのイタリア:入力のTセット、各のみを含む任意の入力" \(Wは、A、S、D \) "の文字列(文字列再び.. 。)。\(W、A、S、 D \) ロボットを表すが、上昇左、下、右方向にスペースすることができます。すべてのロボットを含めることができる最小面積の面積を介してロボットの定義は、グリッドをオフに行ってきました。さて、あなたは(だけのための文字列の任意の位置に文字を追加することができます\(W、A、S、D \)可能ロボットが歩いた最小の面積を求めて、)。

分析:唯一の文字のように、私たちは(唯一の単位長さまたは幅を後退させることができる最小の矩形)を干渉しない横方向の動きおよび長手方向の動きを発見したので、我々は、縦考えると確認横方向の二つのサブ問題に分割することが必要最小面積とすることができます。標準的なプロセスは、よりコンパクトなソリューションを提供しながら、私は、接頭辞と書き込みを考えました。

ACコード

#include <bits/stdc++.h>
#define SIZE 200007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
void io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}
int n, m, t;
string str;
struct node {
    int val;
    int pos;
    int la, lb, ra, rb;
}p1[SIZE], p2[SIZE];
void init1(node p[], int n) {
    int x = INF, y = -INF;
    rep(i, 0, n) {
        p[i].la = min(x, p[i].pos);
        x = min(x, p[i].la);
        p[i].ra = max(y, p[i].pos);
        y = max(y, p[i].ra);
    }
}
void init2(node p[], int n) {
    int x = INF, y = -INF;
    for (int i = n; i >= 0; --i) {
        p[i].lb = min(x, p[i].pos);
        x = min(x, p[i].lb);
        p[i].rb = max(y, p[i].pos);
        y = max(y, p[i].rb);
    }
}
int main() {
    io(); cin >> t;
    while (t--) {
        cin >> str;
        int k = 1, j = 1;
        rep(i, 0, str.length() - 1) {
            if (str[i] == 'W') p1[k++].val = 1;
            else if (str[i] == 'S') p1[k++].val = -1;
            else if (str[i] == 'A') p2[j++].val = 1;
            else p2[j++].val = -1;
        }
        rep(i, 0, k - 1) p1[i].pos = p1[i - 1].pos + p1[i].val;
        rep(i, 0, j - 1) p2[i].pos = p2[i - 1].pos + p2[i].val;
        init1(p1, k - 1); init1(p2, j - 1);
        init2(p1, k - 1); init2(p2, j - 1);
        ll w = p1[k - 1].ra, a = p2[j - 1].la, s = p1[k - 1].la, d = p2[j - 1].ra;
        ll h = p1[k - 1].ra - p1[k - 1].la + 1, wid = p2[j - 1].ra - p2[j - 1].la + 1;
        bool f1 = false, f2 = false;
        rep(i, 0, k - 1) {
            if (p1[i].lb < p1[i].la && p1[i].rb < p1[i].ra) { f1 = true; break; }
            if (p1[i].lb > p1[i].la && p1[i].rb > p1[i].ra) { f1 = true; break; }
        }
        rep(i, 0, j - 1) {
            if (p2[i].lb < p2[i].la && p2[i].rb < p2[i].ra) { f2 = true; break; }
            if (p2[i].lb > p2[i].la && p2[i].rb > p2[i].ra) { f2 = true; break; }
        }
        if (f1 || f2) {
            if (f1 && f2) {
                if (wid > h) cout << wid * (h - 1) << endl;
                else cout << (wid - 1) * h << endl;
                continue;
            }
            if (f1) cout << wid * (h - 1) << endl;
            else cout << (wid - 1) * h << endl;
        }
        else cout << wid * h << endl;
    }
}

 
D.は1337文字列...印刷し
ているイタリア:与えられた正の整数\(N- \) 含む構築\(N-を\)\(1337 \)文字列の部分文字列(または文字列を... )。

分析:我々は、各構成考える\(C_N ^ 2 \) 例えば、完了まで2を、\(10 + 3 + 1 = 6 \) 我々は構築することができる\(13373737 \) しかし、最後に残った2に注意を払うことかもしれないが、構造1回繰り返すことはできません。だから最終的に、我々は、例えば、2を二1の下部3に挿入されるコンストラクト:\を(6 + 2 = 8 \)コンストラクト:\(13311337 \)

ACコード

#include <bits/stdc++.h>
#define SIZE 200007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}
ll n, m, t; bool flag;
ll dp[SIZE];
vector<int> v;
int main() {
    io(); cin >> t;
    rep(i, 1, 100050) dp[i] = 1ll * i * (i - 1) / 2;
    while (t--) {
        cin >> n; m = n; v.clear();
        if (n == 2) { cout << "11337\n"; continue; }
        flag = false;
        while (n) {
            int pos = lower_bound(dp, dp + 100010, n) - dp;
            if (dp[pos] > n) --pos;
            n -= dp[pos];
            v.emplace_back(pos);
            if (n == 2) { flag = true; break; }
        }
        int cnt = 1, it = v.size() - 1;
        cout << "13";
        while (cnt < v[0]) {
            if (flag && cnt == v[0] - 2) cout << "11";
            if (cnt < v[it]) cout << 3;
            else { --it, --cnt; cout << 7; }
            cnt++;
        }
        cout << "7\n";
    }
}

おすすめ

転載: www.cnblogs.com/st1vdy/p/11329097.html