CF1220
CF1220
A
one和zero特的字母分别是'n'和'z'
输出他们的数量即可
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 3e5 + 3;
char s[N];
int sum[N];
int n;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int main(){
n = read();
scanf("%s",s + 1);
for(int i = 1;i <= n;++i) sum[s[i]]++;
int cnt = 0;
while(sum['n']){
cnt++;
printf("1 ");
sum['n']--;
}
while(sum['z']){
printf("0 ");
sum['z']--;
}
return 0;
}
B
给你一个\(n * n\)的矩阵,第\((i,j)\)个位置表示\(a_i \times a_j\)(对角线为\(0\))
求数组\(a\)
对于任意三个\((i,j,k)\)
我们有\(a_i^2 = \frac{a_i \times a_j \times a_k \times a_j}{a_j \times a_k}\)
所以按照这种方式可以求出每个\(a_i^2\),最后开根号即可
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 1005;
LL a[N][N];
LL ans[N];
int n,m;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int main(){
n = read();
for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) a[i][j] = read();
for(int i = 1;i <= n;++i){
int x = 0,y = 0;
if(i <= n - 2) x = i + 1,y = i + 2;
else if(i == n - 1) x = 1,y = n;
else x = 1,y = 2;
ans[i] = a[i][x] * a[i][y] / a[x][y];
}
for(int i = 1;i <= n;++i) printf("%.0lf ",sqrt((double)ans[i]));
return 0;
}
C
给定一个字符串\(s\)
游戏规则
当前在\([l,r]\)每次只能扩展到\([l',r']\)使得\(l' \le l,r \ge r\)且\(s[l',r']\)的字典序比\(s[l,r]\)要小,不能走的时候对方获胜
对于每个\(i\),求出当初始状态为\([i,i]\)时,先手是否必胜
很明显,只要存在\(s[l', r']\)满足条件,那么先手一定可以移动到最优解,那么只需要判断是否存在比现在这个状态字典序更小的状态存在即可
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 1e6 + 3;
char s[N];
int sum[27][N];
int n;
int ans = 0x3f3f3f3f;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int main(){
scanf("%s",s + 1);
n = strlen(s + 1);
for(int i = n;i >= 1;--i){
for(int j = 0;j < 26;++j) sum[j][i] = sum[j][i + 1];
sum[s[i] - 'a'][i]++;
}
for(int i = 1;i <= n;++i){
bool flag = 0;
for(int j = s[i] - 'a' - 1;j >= 0;--j) if(sum[j][1] - sum[j][i] > 0) flag = 1;
if(!flag)
printf("Mike\n");
else printf("Ann\n");
}
return 0;
}
D
题目大意:给定一个正整数集合\(B\)。
让所有整数都为一张无向图中的顶点。\(i, j\)之间有边,当且仅当\(\left| i - j\right| \in B\)
现在要从\(B\)中删去最少的元素,使得这张无向图变成二分图
首先二分图的定义:不存在奇环
首先对于\(B\)中的元素\(x,y\)
若
\]
这个式子如果是奇数,那么存在奇环
我们分类讨论一下
若\(x,y\)是奇数
那么上面的式子一定是偶数
若\(x,y\)是一奇一偶,那么上面的式子是偶数
如果\(x,y\)是偶数
那么我们就设\(x = 2x' ,y = 2y'\)
发现就变成了一个子问题,直到出现一奇一偶或者全是奇数的情况就能判断他们能否共存
发现第三种情况的本质就是这两个数的二进制末尾0个数是否相同
(因为不断除二,判断奇偶性)
所以我们由二推多,末尾0个数相同的可以共存,所以最终答案就是\(n\)减去最多的一类
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 5e5 + 3;
inline LL read(){
LL v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int n;
LL a[N];
LL num[N];
int cnt[N];
int main(){
n = read();
for(int i = 1;i <= n;++i) a[i] = read();
for(int i = 1;i <= n;++i){
LL x = a[i];
while((x & 1) == 0){
num[i]++;
x >>= 1;
}
cnt[num[i]]++;
}
int sum = 0,id = 0x3f3f3f3f;
for(int i = 0;i <= n;++i)
if(sum < cnt[num[i]]) sum = cnt[num[i]],id = num[i];
printf("%d\n",n - sum);
for(int i = 1;i <= n;++i){
if(num[i] != id) printf("%lld ",a[i]);
}
return 0;
}
E
题目大意
给定一个无向图,点有点权(非负),不能连续通过同一条边,一条从\(S\)出发的路径使得点权和最大(重复经过算一次)
(这里的环定义貌似有点奇特,图中的非黄色点都属于环)
首先,如果存在环,那么这和环上的点我们都是可以经过的
所以我们只需要考虑不在换上的点的贡献,之后发现如果我们走进了这种点
就再也不能回头

比如说图中黄色的点,我们一旦从环上走了进去,就只能向下走
我们一定先去把换上的点先跑一边,之后再剩下的点没被经过的点中选一条向下点权和最大的点即可
考虑如何去实现这个过程,首先找环
可以使用类拓扑排序找到环,然后可以证明,环上的点都是可以算进贡献的
是不是我们再寻找一条最大路径就好了
但是注意我们只是讨论了起点再环上的情况
若起点不在环上,最优解可能是这个样子

蓝色部分
也就是说,\(S\)到环上的路径也成为了恒有贡献的部分
(即使最优解在\(S\)的下边我们也可以上去再下来)
所以把这一块也标记一下就好了
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 5e5 + 3;
LL w[N];
struct edge{
int to;
int nxt;
}e[N << 1];
LL f[N];
int n,m;
LL ans,res;
int s;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int tot,cnt;
int head[N],d[N];
bool used[N],flag[N];LL dp[N];
int fa[N];
inline void add(int x,int y){
e[++tot].to = y;
e[tot].nxt = head[x];
head[x] = tot;
}
inline void pre(){
flag[s] = 1;
std::queue <int> q;
for(int i = 1;i <= n;++i) if(d[i] == 1) q.push(i),f[i] = w[i];
while(!q.empty()){
int k = q.front();used[k] = 1;q.pop();
for(int i = head[k];i;i = e[i].nxt){
int y = e[i].to;
if(used[y]) continue;
f[y] = max(f[y],f[k] + w[y]);
flag[y] |= flag[k];
d[y]--;
if(d[y] == 1) q.push(y);
}
}
}
inline void dfs(int x,int f){
for(int i = head[x];i;i = e[i].nxt){
int y = e[i].to;
if(y == f) continue;
dfs(y,x);
dp[x] = max(dp[x],dp[y]);
}
dp[x] += w[x];
}
int main(){
n = read(),m = read();
for(int i = 1;i <= n;++i) w[i] = read();
for(int i = 1;i <= m;++i){
int x = read(),y = read();
add(x,y);
add(y,x);
d[x]++,d[y]++;
}
s = read();
if(m == n - 1){
dfs(s,0);
printf("%lld\n",dp[s]);
return 0;
}
pre();
for(int i = 1;i <= n;++i) if(flag[i]) ans += w[i],f[i] = 0;
for(int i = 1;i <= n;++i){
if(flag[i]) continue;
if(used[i]) res = max(res,f[i]);
else ans += w[i];
}
printf("%lld\n",ans + res);
return 0;
}
CF1220的更多相关文章
- CF1220题解
D 考虑从0出发,两个属于集合的元素\(x,y\) \(ax=by\),则形成奇环需要\(a+b\equiv 1(\% 2)\) 需要无奇环,\(\frac{lcm(x,y)}{x}+\frac{lc ...
随机推荐
- Mybatis自查询递归查找子菜单
之前写过 java从数据库读取菜单,递归生成菜单树 今天才发现mybatis也可以递归查询子菜单 先看一下数据库 主键id,名称name,父id,和url 设计菜单类 public class Men ...
- Leetcode840.Magic Squares In Grid矩阵中的幻方
3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等. 给定一个由整数组成的 N × N 矩阵,其中有多少个 3 × 3 的 & ...
- bzoj2073 PRZ
Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍 ...
- 杨柳目-杨柳科-Info-新闻:杨柳絮造成的危害相关视频资讯
ylbtech-杨柳目-杨柳科-Info-新闻:杨柳絮造成的危害相关视频资讯 1. 杨絮返回顶部 1. 2. https://www.baidu.com/sf/vsearch?pd=video&a ...
- POJ 2632 Crashing Robots (模拟 坐标调整)(fflush导致RE)
题目链接:http://poj.org/problem?id=2632 先话说昨天顺利1Y之后,直到今天下午才再出题 TAT,真是刷题计划深似海,从此AC是路人- - 本来2632是道略微恶心点的模拟 ...
- @codeforces - 1149D@ Abandoning Roads
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 n 点 m 条边的无向连通图,每条边的边权为 a 或 ...
- wepy ——$apply
1.说明 在异步函数中更新数据的时候,必须手动调用 $apply 方法. 2.代码和效果 // html <button type="primary" plain=" ...
- 洛谷P1616 疯狂的采药
//完全背包 #include<bits/stdc++.h> using namespace std; ; ; int n,m,v[maxn],w[maxn],f[maxv]; int m ...
- oracle函数 sqrt(x)
[功能]返回x的平方根 [参数]x数字型表达式 [返回]数字 [示例] select sqrt(64),sqrt(10) from dual; 返回:8 , 3.16227766
- Knative Eventing 中如何实现 Registry 事件注册机制
摘要: 在最新的 Knative Eventing 0.6 版本中新增了 Registry 特性, 为什么要增加这个特性, 该特性是如何实现的.针对这些问题,希望通过本篇文章给出答案. 背景 作为事件 ...