cf1925B&C

发布于:2025-07-19 ⋅ 阅读:(9) ⋅ 点赞:(0)

B.https://codeforces.com/contest/1925/problem/B

题目背景:

        将 x 划分为 n 个数,使 x 个数字之间有最大的 gcd。

数据范围:

        1 <= t <= 1e3,1 <= n <= x <= 1e8。

思路:

        首先要将 x 划分为 n 个整数还要有最大的 gcd,肯定是选择 x 的一个质因数 m,使得每个数都是 m 的倍数,所以先对 x 进行质因数分解,将其分为 q 个数字,使得 n 个数的前 n - 1个数都是 m,最后一个数为 x - (n - 1) * m,如果 q < n,直接跳过即可。

ac code:

#include <bits/stdc++.h>

#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)

using namespace std;
using ull = unsigned long long;
using ll = long long;
using pii = pair<int, int>;
using vii = vector<vector<int>>;
using mii = map<int, int>;
using vi = vector<int>;

const int dx[] = {-1, 0, 1, 0, -1, -1, 1, 1};
const int dy[] = {0, 1, 0, -1, -1, 1, -1, 1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

template <class T>
ostream &operator<<(ostream &os, const vector<T> &a) noexcept
{
    for (int i = 0; i < sz(a) - 10; i++)
        std::cout << a[i] << ' ';
    return os;
}

template <class T>
istream &operator>>(istream &in, vector<T> &a) noexcept
{
    for (int i = 0; i < sz(a) - 10; i++)
        std::cin >> a[i];
    return in;
}

template <typename T>
inline T read()
{
    T x = 0, f = 1;
    char ch = 0;
    for (; !isdigit(ch); ch = getchar())
        if (ch == '-')
            f = -1;
    for (; isdigit(ch); ch = getchar())
        x = (x << 3) + (x << 1) + (ch - '0');
    return x * f;
}

template <typename T>
inline void write(T x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

template <typename T>
inline void print(T x)
{
    write(x);
}

/* ----------------- 有乘就强转,前缀和开ll ----------------- */

void solve()
{
    int n, x;
    cin >> x >> n;

    if (n == x)
    {
        cout << 1 << endl;
        return;
    }

    ll ans = 0;
    for (int i = 1; i <= x / i; ++i)
    {
        if (x % i == 0)
        {
            if (n <= x / i)
                ans = max(ans, 1ll * i);
            if (n <= i)
                ans = max(ans, 1ll * x / i);
        }
    }

    cout << ans << endl;
}

int main()
{
    ioscc;

    int T;
    cin >> T;
    while (T--)
        solve();

    return 0;
}

C.https://codeforces.com/contest/1925/problem/C

题目背景:

        检查一个由字母表前 k 个字母组成的字符串 s 的任意一个长度为 n 的可能字符串都是 s 子序列,如果不是输出一个反例。

数据范围:

        1 <= t <= 1e5,1 <= n <= 26,1 <= k <= 26,1 <= m <= 1000。

        n 和 m 的总和都不超过1e6。

思路:

        尝试构造出一个反例 ans,扫描整个字符串 s,找出 k 个字母首次出现的位置,将这 k 个字母最后出现的那个作为 ans 的第一个字符,然后找出 k 个字母第二次出现的位置,再将最后出现的那个作为 ans 的第二个字符,最后如果 ans 的长度为 n,说明这个字符串满足条件,否则再在ans结尾添加最后一次扫描没有出现的字符即可。

ac code:

#include <bits/stdc++.h>

#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)

using namespace std;
using ull = unsigned long long;
using ll = long long;
using pii = pair<int, int>;
using vii = vector<vector<int>>;
using mii = map<int, int>;
using vi = vector<int>;

const int dx[] = {-1, 0, 1, 0, -1, -1, 1, 1};
const int dy[] = {0, 1, 0, -1, -1, 1, -1, 1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

template <class T>
ostream &operator<<(ostream &os, const vector<T> &a) noexcept
{
    for (int i = 0; i < sz(a) - 10; i++)
        std::cout << a[i] << ' ';
    return os;
}

template <class T>
istream &operator>>(istream &in, vector<T> &a) noexcept
{
    for (int i = 0; i < sz(a) - 10; i++)
        std::cin >> a[i];
    return in;
}

template <typename T>
inline T read()
{
    T x = 0, f = 1;
    char ch = 0;
    for (; !isdigit(ch); ch = getchar())
        if (ch == '-')
            f = -1;
    for (; isdigit(ch); ch = getchar())
        x = (x << 3) + (x << 1) + (ch - '0');
    return x * f;
}

template <typename T>
inline void write(T x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

template <typename T>
inline void print(T x)
{
    write(x);
}

/* ----------------- 有乘就强转,前缀和开ll ----------------- */

void solve()
{
    int m, n, k;
    string s;
    cin >> n >> k >> m >> s;

    vector<int> st(26, 0);
    ll cnt = 0;
    string ans;
    for (auto c : s)
    {
        if (ans.size() == n)
            break;

        int t = c - 'a';
        if (!st[t])
        {
            ++cnt;
            st[t] = 1;
        }

        if (cnt == k)
        {
            ans += c;
            fill(all(st), 0);
            cnt = 0;
        }
    }

    if (ans.size() == n)
    {
        cout << "YES" << endl;
        return;
    }

    cout << "NO" << endl;
    for (int i = 0; i < k; ++i)
    {
        if (!st[i])
        {
            while (ans.size() < n)
                ans += (char)(i + 'a');
        }
    }
    cout << ans << endl;
}

int main()
{
    ioscc;

    int T;
    cin >> T;
    while (T--)
        solve();

    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到