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\)

\[\dfrac{lcm(x,y)}{x} + \frac{lcm(x,y)}{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的更多相关文章

  1. CF1220题解

    D 考虑从0出发,两个属于集合的元素\(x,y\) \(ax=by\),则形成奇环需要\(a+b\equiv 1(\% 2)\) 需要无奇环,\(\frac{lcm(x,y)}{x}+\frac{lc ...

随机推荐

  1. 将数组对象转换成DataSet

    public static DataSet ObjectArrayToDataSet(object[] objArr) { if (objArr.Length == 0) return null; D ...

  2. 外贸电子商务网站之Prestashop paypal支付添加

    1.在https://addons.prestashop.com/en/payment-card-wallet/1748-paypal.html 下载paypal支付模块 2.解压,复制到网站根目录- ...

  3. 开发ArcEngine时的一个提示,无效位图,无法在类“***”中找到资源“***.bmp”

    解决办法:文件属性-生成操作 修改为 :嵌入式资源.

  4. 编程算法 - 字符串的排列 代码(C)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/35593485 字符串的排列 代码(C) 本文 ...

  5. 2017 ACM/ICPC Asia Regional Shenyang Online:number number number hdu 6198【矩阵快速幂】

    Problem Description We define a sequence F: ⋅ F0=0,F1=1;⋅ Fn=Fn−1+Fn−2 (n≥2). Give you an integer k, ...

  6. PHP判断图片格式的七种方法小结

    <?php $imgurl = "http://www.jb51.net/images/logo.gif"; //方法1 echo $ext = strrchr($imgur ...

  7. Python基础:04映射类型

    字典是Python语言中唯一的映射类型.一个字典对象是可变的,它是一个容器类型,能存储任意个数的Python对象.字典中的数据是无序排列的. 映射类型也可被称做哈希表,哈希表的算法是获取键,对键执行一 ...

  8. 巧用 PHP 数组函数

    0x00 前言 PHP 的数组是一种很强大的数据类型,与此同时 PHP 内置了一系列与数组相关的函数可以很轻易的实现日常开发的功能.但是我发现好像很多小伙伴都忽略了内置函数的作用(比如我自己就编写过一 ...

  9. Android 使用SystemBarTint设置状态栏颜色

    做项目时,发现APP的状态栏是系统默认的颜色,突然想到,为啥别的APP是自己设置的颜色(和APP本身很相搭),于是也想给自己的APP设置系统状态栏的颜色,更加美美哒... 搜了下,发现原来设置状态栏居 ...

  10. JQuery---高级选择器

    一.派生选择器 例如:$('#bavBar  a') 二.孩子选择器 例如:$('body > p') 三.相邻兄弟选择器 例如:$('h2 + div') 四.属性选择器 1.$('img[a ...