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;
}
相关推荐
success7 分钟前
【爆刷力扣-链表】画图自见
算法
今晚一定早睡28 分钟前
代码随想录-数组-移除元素
前端·javascript·算法
前端拿破轮35 分钟前
面试官:二叉树的前中后序遍历,用递归和迭代分别实现🤓🤓🤓
数据结构·算法·leetcode
Gyoku Mint1 小时前
深度学习×第10卷:她用一块小滤镜,在图像中找到你
人工智能·python·深度学习·神经网络·opencv·算法·cnn
智者知已应修善业1 小时前
2021-07-21 VB窗体求范围质数(Excel复制工作簿)
经验分享·笔记·算法
C++chaofan2 小时前
45. 跳跃游戏 II
java·开发语言·数据结构·算法·leetcode·游戏·职场和发展
今天你睡了嘛2 小时前
数据结构入门:像整理收纳一样简单!
数据结构
拾光拾趣录2 小时前
举一反三:合并 K 个有序链表的最小堆实现
前端·算法
thginWalker2 小时前
差分数组算法
算法
拾光拾趣录2 小时前
合并K个有序链表
前端·算法