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;
}