@Dmaxiya
2018-08-17T10:24:30.000000Z
字数 5406
阅读 987
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 long
const int maxn = 13;
int A, B;
LL fac[maxn];
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::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 long
const int maxn = 1000 + 100;
int n, m, ans;
char s[maxn], t[maxn];
bool vis[maxn], visans[maxn];
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::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 long
const 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 Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::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 long
const 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 Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::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;
}