Educational Codeforces Round 20

来源:互联网 发布:linux 启动网络服务 编辑:程序博客网 时间:2024/05/17 15:41

A

按题意来即可

#include <bits/stdc++.h>using namespace std;#define LL long long#define pb push_back#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i < n; ++i)const int qq = 1e3 + 10;int gra[qq][qq];int main(){int n, k;scanf("%d%d", &n, &k);for(int i = 1; i <= n; ++i){for(int j = 1; j <= n; ++j){if(gra[i][j] == 1)continue;if(i == j){if(k >= 1)gra[i][j] = 1, k--;}else{if(k >= 2)gra[i][j] = gra[j][i] = 1, k -= 2;}}}if(k){puts("-1");return 0;}for(int i = 1; i <= n; ++i){for(int j = 1; j <= n; ++j)printf("%d ", gra[i][j]);puts("");}return 0;}


B

每个非0距离0的最短距离一定是它左边的第一个0或者它右边的第一个0,计算这两个位置的0即可

#include <bits/stdc++.h>using namespace std;#define LL long long#define pb push_back#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i < n; ++i)const int qq = 2e5 + 10;int num[qq], dist[qq];int main(){int n;scanf("%d", &n);for(int i = 1; i <= n; ++i){scanf("%d", num + i);}int pos = -1;for(int i = 1; i <= n; ++i){if(num[i] == 0){if(pos == -1){for(int j = i - 1; j >= 1; --j)dist[j] = i - j;pos = i;}else{for(int j = i - 1; j > pos; --j)dist[j] = min(dist[j], i - j);pos = i;}continue;}if(pos == -1)continue;dist[i] = i - pos;}for(int i = 1; i <= n; ++i)printf("%d ", dist[i]);puts("");return 0;}


C

题意:给出一个n,一个k,要求在1到n中选k个数,使得和为n,并且这k个数的gcd要最大。

思路:假设选出来的数  a1 + a2 + ... + ak = n, 那么令 g = gcd(a1, a2, ... , ak), 则 b1 + b2 + ... + bk = n/g, 很显然这个g是n的因子,那么我们枚举n的因子判断可行性即可,注意这里n的最大值是1e10, 那么当k大于1e6的时候其实就是不可能的,因为算最小的情况 从1加到1e6是大于1e10的,并且k > n的时候也不可能,排除这两个情况就可以直接做了。

#include <bits/stdc++.h>using namespace std;#define LL long long#define pb push_back#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int qq = 1e5 + 10;int main(){LL n, k;scanf("%lld%lld", &n, &k);if(k >= 1e6 || k > n){puts("-1");return 0;}LL f = (1 + k) * k / 2;LL ans = 0;for(LL i = 1; i * i <= n; ++i){if(n % i == 0){if(i >= f){ans = n / i;break;}else if(n / i >= f){ans = i;}}}if(!ans){puts("-1");return 0;}LL sum = 0;for(int i = 1; i < k; ++i)printf("%lld ", i * ans), sum += i * ans;printf("%lld\n", n - sum);return 0;}




E

题意:给出一个n一个k,然后给出一个长度为n的字符串,字符只有四种,L,W,D,?,分别代表输,赢,平,任意,现在要求在最后一个回合的时要求输赢数的绝对值等于k,并且前面任意一个回合结束以后输赢的绝对值不能等于k,现在问你把?填完,求一种符合要求的解。

思路:dp[i][j]代表第i回合,赢 - 输数为j的字符串是否存在,因为有负数,所以可以把整体向右平移一个n,然后就状态转移就好。

#include <bits/stdc++.h>using namespace std;#define LL long long#define pb push_back#define pill pair<int, int>#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i <= n; ++i)const int qq = 2e3 + 10;int dp[qq][qq], pre[qq][qq];char st[qq];int n, k;int main(){scanf("%d%d", &n, &k);scanf("%s", st + 1);if(k > n){puts("NO");return 0;}dp[0][n] = 1;for(int i = 1; i <= n; ++i){for(int j = 0; j <= n << 1; ++j){if((j == n - k or j == n + k) and i != n)continue;if(st[i] == 'W' and j - 1 >= 0 and dp[i - 1][j - 1])dp[i][j] = 1, pre[i][j] = -1;if(st[i] == 'D' and dp[i - 1][j])dp[i][j] = 1, pre[i][j] = 0;if(st[i] == 'L' and j + 1 <= (n << 1) and dp[i - 1][j + 1])dp[i][j] = 1, pre[i][j] = 1;if(st[i] == '?'){if(dp[i - 1][j - 1] and j - 1 >= 0)dp[i][j] = 1, pre[i][j] = -1;if(dp[i - 1][j])dp[i][j] = 1, pre[i][j] = 0;if(dp[i - 1][j + 1] and j + 1 <= (n << 1))dp[i][j] = 1, pre[i][j] = 1;}}}//printf("%d %d\n", dp[n][n + k], dp[n][n - k]);if(!dp[n][n - k] and !dp[n][n + k]){puts("NO");return 0;}int a = n, b;if(dp[n][n + k])b = n + k;elseb = n - k;while(a > 0){if(pre[a][b] == -1)st[a] = 'W';else if(pre[a][b] == 1)st[a] = 'L';elsest[a] = 'D';b = b + pre[a][b];a = a - 1;}printf("%s\n", st + 1);return 0;}



F

题意:给出n个数,要求求出gcd = 1的子序列的数量

思路:我们可以处理出gcd = i * k (k = 1, 2, 3 ......) 的个数,如果我们要求出gcd = i的数量 就减去gcd等于i的倍数即可得到

#include <bits/stdc++.h>using namespace std;#define LL long long#define pb push_back#define mst(a, b)memset(a, b, sizeof a)#define REP(i, x, n)for(int i = x; i < n; ++i)const int qq = 1e5 + 10;const int MOD = 1e9 + 7;LL ans[qq], p[qq];LL num[qq];int main(){int n;scanf("%d", &n);p[0] = 1;for(int i = 1; i <= n; ++i)p[i] = (p[i - 1] * 2LL) % MOD;int maxn = 0;for(int i = 1; i <= n; ++i){int x;scanf("%d", &x);maxn = max(maxn, x);num[x]++;}for(int i = 1; i<= maxn; ++i){for(int j = i + i; j <= maxn; j += i)num[i] += num[j];}for(int i = maxn; i > 0; --i){ans[i] = p[num[i]] - 1;for(int j = i + i; j <= maxn; j += i)ans[i] = (ans[i] - ans[j] + MOD) % MOD;}printf("%lld\n", ans[1]);return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 隔壁太吵怎么办阴招 楼上有小孩太吵怎么办 捷达小水管睹了怎么办 楼房下水管冻了怎么办 一楼地面很潮湿怎么办 新房子地面有裂缝怎么办 地砖下面的下水管漏水怎么办 速冻饺子冻在一起了怎么办 牛排泡水解冻了怎么办 饺子都粘一起了怎么办 把桃子放冷冻了怎么办 抖音小视频连不上网怎么办 网络视频连不上网怎么办 苹果8视频不清晰怎么办 乳疮腐烂还臭怎么办 冰箱肉腐烂很臭怎么办 指环扣松了怎么办视频 奇迹mu端游杀人了怎么办 奇迹最强者号找不着了怎么办 v领地退不了押金怎么办 全民奇迹sf钻石变负数怎么办 电脑上的新建没有了怎么办 火车上行李箱砸人怎么办 违建拆除后怎么办房产证 外地车遇到限号怎么办 双号限行 违了怎么办 下高速当地限行怎么办 下高速发现限号怎么办 下高速正好限号怎么办 限号不让下高速怎么办 我的歌没有编曲怎么办 奇迹暖暖以前的账号怎么办 孕妇误吃桃胶了怎么办? 孕4个月吃了桃胶怎么办 刚怀孕吃了桃胶怎么办 额头被打了个包怎么办 裤子被84掉颜色怎么办 高中生晚上偷家里电脑上网怎么办 住高层睡不好觉怎么办 水瓶座如果恨我们了该怎么办 不锈钢保温瓶不保温了怎么办