A - Three swimmers

首先看一下 $p$ 是否能被其中某个数整除,这样答案就是 $0$,否则答案就是 $\min( a-p\bmod a, b-p\bmod b, c - p\bmod c )$。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
ll a, b, c, p;

inline void solve()
{
    cin >> p >> a >> b >> c;
    ll ans = a - p
    ans = min(ans, b - p
    ans = min(ans, c - p
    if (p
        ans = 0;
    cout << ans << '\n';
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

B - Card Deck

贪心。每次找当前没有被放进 $p'$ 的最大的元素的位置,把它及之后的牌都放进 $p'$ 就行。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int n, p[N], ans[N], pos[N], tot;

inline void solve()
{
    tot = 0;
    scanf(
    for (int i = 1; i <= n; ++i)
        scanf(
    int nowpos = n;
    for (int num = n; num; --num)
    {
        if (pos[num] > nowpos)
            continue;
        for (int j = pos[num]; j <= nowpos; ++j)
            ans[++tot] = p[j];
        nowpos = pos[num] - 1;
    }
    for (int i = 1; i <= n; ++i)
        printf(
    puts("");
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

C - Maximum width

贪心的话,不难看出答案是 $t$ 中相邻两字母在 $s$ 中一个在最左一个在最右,并且还要满足子序列匹配关系。那就求出 $t$ 中每个位置能够匹配到 $s$ 中最左和最右分别是哪,记为 $pl(i), pr(i)$,那么答案就是 $\max_{i=1}^{|t|-1}(pr(i+1)-pl(i) )$。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int n, m, ans;
char s[N], t[N];
int pl[N], pr[N];

inline void solve()
{
    scanf(
    scanf(
    int j = 1;
    for (int i = 1; i <= n && j <= m; ++i)
    {
        if (s[i] == t[j])
            pl[j] = i, j++;
    }
    j = m;
    for (int i = n; i && j; --i)
    {
        if (s[i] == t[j])
            pr[j] = i, j--;
    }
    for (int i = 1; i < m; ++i)
        ans = max(ans, pr[i + 1] - pl[i]);
    printf(
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    // scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

D - Genius's Gambit

细节题好恶心啊啊啊啊啊啊啊

在纸上画画可以发现,对于 100000...0 - 1 这种,前面有 $k$ 个 0 的话,这个结果就会产生 $k$ 个 1。并且被减数和减数可以加上任意相同的值,即 $x$ 和 $y$ 中只有两个位置不同,他们间隔为 $k$,那么就可以构造。

但是写的时候要注意各种细节......因为这题有个条件:不能有前导 0,于是就要各种判断,甚么 k=1,b=0,a=0 等等。答案无解的一个充分条件是 $a+b-2<k$,这个可以计算得到。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int a, b, k;
string x, y;

inline void solve()
{
    cin >> a >> b >> k;
    if (max(0, b - 2 + a) < k || (b - 1 + a == k && k != 0) || (b == 1 && k != 0) || (a == 0 && k != 0))
        return puts("No"), void();
    puts("Yes");
    if (k == 0)
    {
        for (int i = 1; i <= b; ++i)
            x += '1', y += '1';
        for (int i = 1; i <= a; ++i)
            x += '0', y += '0';
        cout << x << endl
             << y << endl;
        return;
    }
    x += '1', y += '1';
    x += '1';
    int cnt0 = 0, cnt1 = 2;
    for (int i = 1; i <= min(a - 1, k - 1); ++i)
        x += '0', cnt0++;
    for (int i = 1; i < k - cnt0; ++i)
        x += '1', cnt1++;
    x += '0', cnt0++;
    for (int i = 1; i <= cnt0; ++i)
        y += '0';
    for (int i = 1; i <= k - cnt0; ++i)
        y += '1';
    y += '1';
    for (int i = 1; i <= a - cnt0; ++i)
        x += '0', y += '0';
    for (int i = 1; i <= b - cnt1; ++i)
        x += '1', y += '1';
    cout << x << endl
         << y << endl;
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    // scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

E - Almost Fault-Tolerant Database

如果第一个串就符合条件的话,那么后面所有的串与其相差最多不超过 2。但是现在涉及到修改,那么可以看出最多只能对第一个串改两个位置。接下来就开始搜索(


```dfs(b, leftcnt, step)``` 表示当前的答案序列为 b,还剩 leftcnt 次修改次数,当前在检查第 step 个序列。那么就需要分情况:```leftcnt=0``` 的话,那么接下来就不能修改了,直接 check 当前答案序列是否合法即可。不合法就回溯;```leftcnt=1``` 的话,那么还能修改一次,检查一下 ```a[step]``` 和 ```b``` 之间差几个位置,大于 3 个就无论如何也不行,就枚举修改的位置即可。后面的讨论同理。

时间复杂度 $\mathcal{O}(n)$。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int n, m, vis[N];
vector<int> a[N], b;
vector<int> getdiff(vector<int> &x, vector<int> &y)
{
    vector<int> ret;
    for (int i = 1; i <= m; ++i)
        if (x[i] != y[i])
            ret.push_back(i);
    return ret;
}

bool check(vector<int> &b)
{
    for (int i = 2; i <= n; ++i)
        if (getdiff(b, a[i]).size() > 2)
            return 0;
    return 1;
}

void dfs(vector<int> &b, int leftcnt, int step)
{
    if (leftcnt == 0)
    {
        if (!check(b))
            return;
        cout << "Yes" << endl;
        for (int i = 1; i <= m; ++i)
            cout << b[i] << ' ';
        exit(0);
    }
    if (step == n + 1)
    {
        if (!check(b))
            return;
        cout << "Yes" << endl;
        for (int i = 1; i <= m; ++i)
            cout << b[i] << ' ';
        exit(0);
    }
    else if (leftcnt == 1)
    {
        auto v = getdiff(b, a[step]);
        if (v.size() > 3)
            return;
        if (v.size() == 3)
            for (auto i : v)
            {
                if (vis[i])
                    continue;
                b[i] = a[step][i], vis[i] = 1;
                dfs(b, leftcnt - 1, step + 1);
                b[i] = a[1][i], vis[i] = 0;
            }
        else
            dfs(b, leftcnt, step + 1);
    }
    else if (leftcnt == 2)
    {
        auto v = getdiff(b, a[step]);
        if (v.size() > 4)
            return;
        if (v.size() == 3)
        {
            for (auto i : v)
            {
                if (vis[i])
                    continue;
                b[i] = a[step][i], vis[i] = 1;
                dfs(b, leftcnt - 1, step + 1);
                b[i] = a[1][i], vis[i] = 0;
            }
            for (int l = 0; l < 3; ++l)
                for (int r = l + 1; r < 3; ++r)
                {
                    if (vis[v[l]] || vis[v[r]])
                        continue;
                    b[v[l]] = a[step][v[l]], b[v[r]] = a[step][v[r]], vis[v[l]] = vis[v[r]] = 1;
                    dfs(b, leftcnt - 2, step + 1);
                    b[v[l]] = a[1][v[l]], b[v[r]] = a[1][v[r]], vis[v[l]] = vis[v[r]] = 0;
                }
        }
        else if (v.size() == 4)
        {
            for (int l = 0; l < 4; ++l)
                for (int r = l + 1; r < 4; ++r)
                {
                    if (vis[v[l]] || vis[v[r]])
                        continue;
                    b[v[l]] = a[step][v[l]], b[v[r]] = a[step][v[r]], vis[v[l]] = vis[v[r]] = 1;
                    dfs(b, leftcnt - 2, step + 1);
                    b[v[l]] = a[1][v[l]], b[v[r]] = a[1][v[r]], vis[v[l]] = vis[v[r]] = 0;
                }
        }
        else
            dfs(b, leftcnt, step + 1);
    }
}

inline void solve()
{
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        a[i].resize(m + 5);
    b.resize(m + 5);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            cin >> a[i][j];
    for (int i = 1; i <= m; ++i)
        b[i] = a[1][i];
    dfs(b, 2, 2);
    cout << "No" << endl;
}

int main()
{
    ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
    TIME__START = clock();
    int Test = 1;
    // scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}