@Dmaxiya
2018-08-17T02:24:30.000000Z
字数 5406
阅读 1208
Codeforces
Contests 链接:Codeforces Round #422 (Div. 2)
过题数:2
排名:1873/13732
求 ,其中 。
输入包含两个整数 。
输出 和 的最大公约数。
| 输入 | 输出 | 提示 |
|---|---|---|
| 4 3 | 6 | ,所以 。 |
。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 13;int A, B;LL fac[maxn];int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);fac[0] = 1;for(int i = 1; i < maxn; ++i) {fac[i] = fac[i - 1] * i;}while(scanf("%d%d", &A, &B) != EOF) {printf("%I64d\n", fac[min(A, B)]);}return 0;}
给定两个字符串 和 ,可以将字符串 任意位置上的字符改为
'?',使 能够匹配 的某个子串,在匹配过程中, 串中的'?'可以匹配任意字符,问最少需要修改多少个字符为'?'才能使得 可以匹配 的某个子串。
第一行包含两个整数 ,分别表示字符串 和 的长度,第二行为字符串 ,第三行为字符串 ,字符串只包含小写字母。
第一行为一个整数 ,表示最少需要修改的字符数,第二行为 个整数,每个整数表示需要修改的字符在 中的位置。如果有多解输出任意一组。
| 输入 | 输出 |
|---|---|
| 3 5 abc xaybz |
2 2 3 |
| 4 10 abcd ebceabazcd |
1 2 |
对于 的每个长度为 的子串计算与 串的不同字符数的最小值,并将不同字符的位置记录下来,就是答案。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 1000 + 100;int n, m, ans;char s[maxn], t[maxn];bool vis[maxn], visans[maxn];int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d%d", &n, &m) != EOF) {ans = n;for(int i = 1; i <= n; ++i) {visans[i] = true;}scanf("%s%s", s + 1, t + 1);for(int i = 1; i <= m - n + 1; ++i) {int tmp = 0;memset(vis, 0, sizeof(vis));for(int j = 0; j < n; ++j) {if(s[j + 1] != t[i + j]) {vis[j + 1] = true;++tmp;}}if(tmp < ans) {ans = tmp;memcpy(visans, vis, sizeof(vis));}}bool flag = false;printf("%d\n", ans);for(int i = 1; i <= n; ++i) {if(visans[i]) {if(flag) {printf(" ");}printf("%d", i);flag = true;}}printf("\n");}return 0;}
的老板给她放了 天的假,她从旅行社那里拿到了所有的行程表以及花费 ,分别表示第 个行程从第 天出发,第 天回来,需要花费 元,期间经过 天。 想要挑选两次不相交的行程,且这两次行程总的旅行天数和正好为 天,两段行程不相交等价于 或者 ,问在满足以上条件的情况下的最小花费。
第一行包含两个整数 ,接下去 行每行三个整数 。
如果无法找到两个不相交且天数和等于 的行程,则输出 ,否则输出最小花费。
| 输入 | 输出 | 提示 |
|---|---|---|
| 4 5 1 3 4 1 2 5 5 6 1 1 2 4 |
5 | 应该选择第 个和第 个行程,这样行程的总天数等于 ,且总花费为 。 |
| 3 2 4 6 3 2 4 1 3 5 4 |
-1 | 每一个行程的区间长度都为 ,所以无法找到合适的旅行方案。 |
先将所有行程按左端点排序,枚举每一个行程 ,将所有满足 的行程记录下来,记录第 个行程的天数所对应的最小花费,就可以 地查询出 对应的天数的最小花费,对每一个行程取最小值就是答案。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 200000 + 100;struct Node {int l, r;LL cost;};bool operator<(const Node &a, const Node &b) {return a.l < b.l;}bool cmp(const Node &a, const Node &b) {return a.r < b.r;}int n, x, day;LL ans;LL cost[maxn];Node node[maxn], ntmp[maxn];int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d%d", &n, &x) != EOF) {ans = INT_MAX;memset(cost, 0x3f, sizeof(cost));for(int i = 0; i < n; ++i) {scanf("%d%d%I64d", &node[i].l, &node[i].r, &node[i].cost);ntmp[i] = node[i];}sort(node, node + n);sort(ntmp, ntmp + n, cmp);int Index = 0;for(int i = 0; i < n; ++i) {while(ntmp[Index].r < node[i].l) {day = ntmp[Index].r - ntmp[Index].l + 1;cost[day] = min(cost[day], ntmp[Index].cost);++Index;}day = node[i].r - node[i].l + 1;if(day >= x) {continue;}ans = min(ans, node[i].cost + cost[x - day]);}if(ans == INT_MAX) {printf("-1\n");} else {printf("%I64d\n", ans);}}return 0;}
在一次选美大赛中,有 个小姐姐参加比赛,比赛规则为:将 个小姐姐分到各个组里,每组 人,在每组之间先两两进行比较选出小组的优胜者,每组内的比较次数为 ,其中的 名优胜者继续分组比赛,直到产生最后的优胜者。
设 为当比赛人数为 时最小的比较次数,要求计算 对 取模的结果。
输入包含三个整数 。
输出答案。
| 输入 | 输出 | 提示 |
|---|---|---|
| 2 2 4 | 19 | 显然 ,而对于 ,如果有 个选手参赛,可以将她们分为两组, 每组两人,则组内比较次数为 ,第一轮需要比较 次,第二轮为每组的优胜者(共 人), 经过 次比较可以得出优胜者;也可以将 个人直接分到同一组,那么总的比较次数为 次,因此最小的比较次数为 ,所以 ,代入公式可以计算出答案为 。 |
由题可知,组内比较次数随着组内人数的增加平方级地增长,所以应该将每一轮的分组尽可能地多,每组人数尽可能少,才能使 最优,如果 为质数,则 ,否则 ,其中 为 的最小的质因数,公式的其他部分直接 求解即可。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 5000000 + 100;const LL MOD = 1000000000 + 7;int cnt;LL t, l, r;LL f[maxn], prime[maxn];bool vis[maxn];void Prime() {cnt = 0;for(LL i = 2; i < maxn; ++i) {if(!vis[i]) {prime[cnt++] = i;}for(LL j = 0; j < cnt && i * prime[j] < maxn; ++j) {LL k = i * prime[j];vis[k] = true;if(i % prime[j] == 0) {break;}}}}LL get(LL x) {if(!vis[x]) {return x * (x - 1) / 2;}LL ret = 0;for(int i = 0; prime[i] * prime[i] <= x; ++i) {if(x % prime[i] == 0) {ret = f[prime[i]] * (x / prime[i]);x /= prime[i];break;}}ret %= MOD;ret += f[x];return ret;}int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);Prime();for(int i = 2; i < maxn; ++i) {f[i] = get(i) % MOD;}while(scanf("%I64d%I64d%I64d", &t, &l, &r) != EOF) {LL ans = 0;LL tt = 1;for(LL i = l; i <= r; ++i) {ans = (ans + (tt * f[i]) % MOD) % MOD;tt = (tt * t) % MOD;}printf("%I64d\n", ans);}return 0;}