「解题报告」2023-10-29 模拟赛
魔法串#
(magic.cpp/c/pas)magic.in magic.out
【问题描述】
小 最近在沉迷数学问题。
对于一个数字串 ,如果可以将它划分成两个数字 、,满足:
1、 。
2、 、 均不包含前导 。
3、 是 的倍数,且是完全立方数。
那么小 就认为该划分是一个“好划分”。 如对于数字串“”,(, )就是一个“好划分”。
如果一个数字串 至少有两个“好划分”,那么小 就认为 是一个“魔法串”。如数字串“”就是一个“魔法串”,其“好划分”有(, )和(,)。
现在给定正整数 ,小 需要你帮她求出一个长度恰好为 的“魔法串”,如果无解请输出“QwQ”(不带引号)。
【输入】
一行一个正整数 。
【输出】
一行一个长度恰好为 的“魔法串”, 如果无解请输出“QwQ”(不带引号) 。
【输入输出样例】
19
【输出样例】
1124784124392112128
【数据范围】
对于 的数据: 。
对于 的数据: 。
对于 的数据: 。
当 时无解。
如果数字串 是一个魔法串,那么向 后面添加 “” 后得到的新串也是一个魔法串。那所以只需要求出 时的可行解,就可以推广到所有情况。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))
#define orz puts("sym, cjx, gjh AK IOI!!!");
template<typename T>
inline T read() {
T x = 0;
bool fg = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
fg |= (ch == '-');
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return fg ? -x : x;
}
const int N = 40;
int n, tmpn;
int num[N];
bool vis[10000005];
void work() {
int cnt = 0;
rep (i, 2, tmpn, 1) {
bool fg = 0;
ll res1 = 0, res2 = 0;
rep (j, 1, i - 1, 1) {
res1 = res1 * 10 + num[j];
if (!res1) {
fg = 1;
break ;
}
}
if (fg) continue ;
rep (j, i, tmpn, 1) {
res2 = res2 * 10 + num[j];
if (!res2) {
fg = 1;
break ;
}
}
if (fg) continue ;
if (res2 % res1 == 0) {
ll tmp = res2 / res1;
if (!vis[tmp]) continue ;
++ cnt;
}
}
if (cnt < 2) return ;
rep (j, 1, tmpn, 1) {
printf("%d", num[j]);
}
rep (j, tmpn + 1, n, 1) {
printf("0");
}
putchar('\n');
exit(0);
}
void dfs(int u) {
if (u > tmpn) {
work();
return ;
}
rep (i, 0, 9, 1) {
if (i == 0 && u == 1) {
continue ;
}
num[u] = i;
dfs(u + 1);
}
}
int main() {
freopen("magic.in", "r", stdin);
freopen("magic.out", "w", stdout);
for (ll i = 1; i <= 1000; ++ i) {
if (i * i * i > 10000000) break ;
vis[i * i * i] = 1;
}
n = read<int>();
int tmp = n - 4;
tmp %= 3;
switch(tmp) {
case 0:
tmpn = 7;
break ;
case 1:
tmpn = 5;
break ;
case 2:
tmpn = 6;
break ;
}
dfs(1);
puts("QwQ");
fclose(stdin);
fclose(stdout);
return 0;
}
配对#
(pair.cpp/c/pas)pair.in pair.out
【问题描述】
有 一共 个数, 为偶数。小 要把这 个数随机地两两配对。令每一对的权值为它们两个数的和。小 想要知道这 对里最大的权值的期望是多少。请输出答案对 取模的值。
【输入】
一行一个正整数 。
【输出】
一行一个整数,表示答案对 取模的值。
【输入样例】
4
【输出样例】
6
【数据范围】
对于 的数据: 。
对于 的数据: 。
对于 的数据: 。
考虑枚举答案是否
转化成答案是否
把分成两部分,一部分是的,一部分是的。
显然的只能和的匹配。
我们从大到小枚举的部分,每次都有种选择,故方案数为
剩下的部分是一个完全图,令为个点的方案数,为
预处理阶乘后可以进行计算。
// The code was written by yifan, and yifan is neutral!!!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug puts("NOIP rp ++!");
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))
template<typename T>
inline T read() {
T x = 0;
bool fg = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
fg |= (ch == '-');
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return fg ? ~x + 1 : x;
}
template<typename T>
void write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) {
write(x / 10);
}
putchar(x % 10 + '0');
}
template<typename T>
void print(T x, char c) {
write(x);
putchar(c);
}
const int N = 5e5 + 5;
const int mod = 1e9 + 7;
ll n;
ll inv[N], pri[N];
ll qpow(ll x, ll y) {
ll ret = 1;
while (y) {
if (y & 1) {
ret = ret * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return ret;
}
int main() {
freopen("pair.in", "r", stdin);
freopen("pair.out", "w", stdout);
n = read<int>();
inv[0] = pri[0] = 1;
rep (i, 1, n / 2, 1) {
pri[i] = pri[i - 1] * (2 * i - 1) % mod;
}
inv[n / 2] = qpow(pri[n / 2], mod - 2) % mod;
per (i, n / 2 - 1, 1, 1) {
inv[i] = inv[i + 1] * (2 * i - 1) % mod;
}
ll ans = 0, las = 0;
rep (v, n + 1, 2 * n - 1, 1) {
int k = n - v / 2;
ll z = qpow(v - n, k) % mod * pri[v / 2 - n / 2] % mod;
ans = (ans + 1ll * v * (((z - las) % mod + mod) % mod) % mod) % mod;
las = z;
}
printf("%lld\n", (ans * inv[n / 2]) % mod);
return 0;
}
幸运数#
(lucky.cpp/c/pas)lucky.in lucky.out
【问题描述】
对于任意两个非零整数 ,,若整数 能同时被 和 整除,则称 为 与 的公约数。定义 与 的最大公约数 为 与 的最大的公约数。
如 ,等等。
这里,我们定义什么是幸运数:
对于一个正整数 ,我们使用 表示 在十进制表示下,按从低位到高位顺序的第 位数字。
设 表示 的奇数位的数字之和,即 ;
设 表示 的偶数位的数字之和,即 ;
若 与 均大于 ,且 与 的最大公约数不超过 ,则称 为幸运数。其中 是一个已知的常数。
举个例子来说,若 ,则 。此时 与 的最大公约数即 等于 。则当 不小于 时 是幸运数。
小 请你回答下面的问题:
对于给定的 ,在不小于 并且不超过 的所有整数中,有多少个数是幸运数?
注意,输入文件包含多组测试数据。
【输入文件】
第一行包含一个整数 ,表示有 组测试数据。
接下来 行,每行包含三个整数 ,表示一次询问。
【输出文件】
输出 行,每行一个整数,依次表示每组测试数据的答案。
【输入样例】
5
1 1 10
2 28 34
100 987654321 987654321
1 1 50000
1 50001 100000
【输出样例】
0
5
1
30298
30309
【样例解释】
时, 到 之间不存在幸运数。
时, 到 之间的幸运数有 ,共 个。
时, 是幸运数。
时, 到 之间的幸运数有 个, 到 之间的幸运数有 个。
【数据规模和约定】
对于 的数据:。
另有 的数据:。
另有 的数据:。
对于 的数据:。
对于 的数据:。
60 pts:
设 为在第 位,奇数位上的数的和为 ,偶数位上的数的和为 ,进行数位 DP。
// The code was written by yifan, and yifan is neutral!!!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug puts("NOIP rp ++!");
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))
template<typename T>
inline T read() {
T x = 0;
bool fg = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
fg |= (ch == '-');
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return fg ? ~x + 1 : x;
}
template<typename T>
void write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) {
write(x / 10);
}
putchar(x % 10 + '0');
}
template<typename T>
void print(T x, char c) {
write(x);
putchar(c);
}
int T;
ll k, l, r;
int a[100];
ll f[25][180][180];
ll dfs(int dig, int lim, ll sum1, ll sum2) {
if (dig == 0) {
if (sum1 && sum2 && __gcd(sum1, sum2) <= k) {
return 1;
}
return 0;
}
if ((!lim) && (~f[dig][sum1][sum2])) {
return f[dig][sum1][sum2];
}
int num = lim ? a[dig] : 9;
ll ans = 0;
rep (i, 0, num, 1) {
ll tmp1 = sum1, tmp2 = sum2;
if (dig & 1) {
tmp1 += i;
} else {
tmp2 += i;
}
ans += dfs(dig - 1, lim && i == a[dig], tmp1, tmp2);
}
if (!lim) {
f[dig][sum1][sum2] = ans;
}
return ans;
}
ll solve(ll n) {
int cnt = 0;
while (n) {
a[++ cnt] = n % 10;
n /= 10;
}
return dfs(cnt, 1, 0, 0);
}
void work() {
memset(f, -1, sizeof f);
k = read<ll>(), l = read<ll>(), r = read<ll>();
cout << solve(r) - solve(l - 1) << '\n';
}
int main() {
freopen("lucky.in", "r", stdin);
freopen("lucky.out", "w", stdout);
T = read<int>();
while (T --) {
work();
}
return 0;
}
作者:yifan0305
出处:https://www.cnblogs.com/yifan0305/p/17796244.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
转载时还请标明出处哟!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】