cf1925B&C

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:

cpp 复制代码
#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:

cpp 复制代码
#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;
}
相关推荐
Jerry8 小时前
LeetCode 28. 找出字符串中第一个匹配项的下标
算法
Jerry10 小时前
LeetCode 459. 重复的子字符串
算法
海石13 小时前
1500分的题目,确实有实力,不过还是我略胜一筹
算法·leetcode
海石13 小时前
【记忆化搜索】条条大路通AC,走好适合你的那一条,走到后再考虑走得快
算法·leetcode
Jerry15 小时前
LeetCode 151. 反转字符串中的单词
算法
gugucoding15 小时前
31. 【C语言】堆栈与队列的实现
c语言·开发语言·数据结构·链表
ChaoZiLL17 小时前
我的数据结构3——链表(link list)
数据结构·链表
a11177617 小时前
LM 算法迭代过程动画演示(SLAM)
算法
头茬韭菜17 小时前
Context 的生死抉择:四层压缩、截断算法与 Session Memory
算法·ai
Jerry17 小时前
LeetCode 541. 反转字符串 II
算法