Codeforces Round #796 (Div. 2)(A~E题题解)
文章目录
原题链接:
A.Cirno’s Perfect Bitmasks Classroom

思路
对于x,如果x里面含有两个1,那么最小答案就是x的最低一位1所构成的数字。(最低一位and可以是非零,高位与另一个1异或,也是非零)。
如果要是x只有一个1,那么所产生的数字在这一位要有一个1,并且在最低的0位还要有一个1这样,才能保证最后的数字非零。
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
int ans;
int x;
cin >> x;
int low1;
int low0;
int cnt1;
low1 = low0 = -1;
cnt1 = 0;
bool fir1 = false;
bool fir0 = false;
for(int i = 0; i <= 31; i++)
{
int t = (x>>i) & 1;
if(!t && !fir0)
{
fir0 = true;
low0 = i;
}
if(t)
{
cnt1 ++;
if(!fir1)
{
low1 = i;
fir1 = true;
}
}
}
if(cnt1 > 1)
{
ans = (1<<low1);
}
else
{
ans = (1 << low1) + (1 << low0);
}
printf("%d\n", ans);
}
return 0;
}
B.Patchouli’s Magical Talisman

思路
使用的H数组,可以较快地求出最低的1是在哪一位。
H数组的大小稍微大一点没有问题。但是最后必须要mod37.可以处理的范围是0到(1<<35)%37.
在题目中,对于一个偶数,有两种操作:
- 把这个偶数除以2,但是可能会有偶数经过一次操作不能变成奇数,例如8
- 把偶数和奇数合在一起,这样就只需要1次就可以消灭一个偶数。
所以有贪心策略。
对于一个数列,如果存在奇数,那么最终所需要的操作次数就是所有偶数的个数之和(全部和奇数进行合并)
如果要是,没有偶数,那么就寻找把偶数变成奇数的最小操作次数,然后加上所有的偶数的个数。
代码
#include <bits/stdc++.h>
using namespace std;
int H[50];
void process()
{
for(int i = 0; i <= 35; i++)
{
H[((long long)1 << i)%37] = i;
}
}
int main()
{
process();
int T;
cin >> T;
while(T--)
{
int ans;
int num_even = 0;
int minn = INT_MAX;
int buf;
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &buf);
if(H[(buf & (-buf))%37] != 0)
{
num_even ++;
}
minn = min(minn, H[(buf & (-buf))%37]);
}
if(minn == 0)
ans = num_even;
else
ans = num_even-1+minn;
printf("%d\n", ans);
}
return 0;
}
C.Manipulating History

思路
一定要从题目的描述中跳出来,题目说的很复杂,但是要找一种更加合理的规律。
如果直接按照题目的进行,显然是不可行的。

所以把所有字母全部统计一遍,如果不是偶数,那么就是开始的哪一个字母
代码
#include <bits/stdc++.h>
using namespace std;
#define N 200010
char buf[N];
int cnt[300];
int main()
{
int T;
cin >> T;
while(T--)
{
char ans;
memset(cnt, 0, sizeof(cnt));
int n;
scanf("%d", &n);
for(int i = 1; i <= 2*n+1; i++)
{
scanf("%s", buf+1);
int len = strlen(buf+1);
for(int j = 1; j <= len; j++)
{
int p = buf[j];
cnt[p] = (cnt[p]+1) % 2;
}
}
for(int i = 'a'; i <= 'z'; i++)
{
if(cnt[i]&1 == 1)
{
ans = i;
break;
}
}
printf("%c\n", ans);
}
return 0;
}
D.The Enchanted Forest

思路
这一道题目中有两个贪心的维度
- 我要尽量把刚开始的蘑菇取的尽可能多。
这样的贪心策略就是不走回头路。 - 第二,我要把新产生的蘑菇尽可能地贪完。
由于蘑菇是在不断地生长,如果正过来考虑,会迷失方向,倒过来考虑,在给定时间内,长出的蘑菇是一个定值。而我每一个位置上的蘑菇与我最后到达这一点是在什么时候有关。
如果是最后一次到的那么这里剩下的就是1个蘑菇,如果是最后一次是倒数第二次到的,那么这里剩下的就是2个蘑菇。。。使用在给定时间内,长出的蘑菇总量减去最后剩下的蘑菇,就是我得到的到的生长出来的蘑菇。容易得到,最后的路径一定是单向的(如果时间可以走完全图,那么最后几次一定是从最左面到最右面。如果不能走完全图,一定是某个点一直往一个方向)
所以分为两种情况:
- 如果不能走完全图,那么就用尺取法,找到区间蘑菇最多的数目。然后加上第二种情况的最优值。
- 否则就所有蘑菇加上第二种的最优值。
代码
#include <bits/stdc++.h>
using namespace std;
#define N 200010
int s[N];
int main()
{
int T;
cin >> T;
while(T--)
{
long long ans = 0;
int n, k;
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++)
{
scanf("%d", s+i);
}
if(k >= n)
{
for(int i = 1; i <= n; i++)
{
ans += s[i];
}
ans += (long long)(k-1) * n;
ans -= (long long)n * (n-1) / 2;
}
else
{
long long tmp = 0;
int l = 1;
int r = k;
for(int i = 1; i <= r; i++) tmp += s[i];
ans = tmp;
while(r+1 <= n)
{
tmp-=s[l++];
tmp+=s[++r];
ans = max(tmp, ans);
}
ans += (long long)k*(k-1)/2;
}
printf("%lld\n", ans);
}
return 0;
}
E.Railway System

题目大意
有n个节点,m条边,你可以询问2m次,询问的m串中为1,代表包含这条边,如果为0,就代表不包含这条边。在这种情况下,会得到最大生成树的权值。
然后最后得出最小生成树的权值。
思路
这道题目需要知道最小生成树的克鲁斯卡尔算法。
对于最大生成树,可以进行类推:从把所有的边进行从大到小的排序,然后从最大的边开始,如果加上这一条边不会构成环,那么就选择这一条边。否则不选择这条边。
证明:按照树的定义:数的边数m是图的定点数n的n-1。
假设遇到一条边,满足与已经选择的边不构成回路,但是没有选择,那么在按照这种方法得到最大生成树之后,加上这条边,一定有回路。而这条边与比他大的边不会构成回路,那么只能是与比他小的边构成回路。这样的话,删除比他小的边,又称为了一颗树,但是权值比之前的大。
得证!
所以对于当前的最大的边,一定被选择在最大生成树里面。
如果把这条边删除,有两种情况
- 这条边是割边(删除之后图的连通分支会增加一)

那么删除之后,最大生成树的权值相比上一回,会减少这条边的权值。 - 如果删除之后还有回路,那么对于一种情况:使用回路来替代他,那么这种情况下,删除这条边的前后两次权值之差已经小于这条边的权值。如果还有更长的情况,那么删除前后权值的差值只会更小。
对于割边,最小生成树里面一定有它。而对于可以替代的边,最小生成树里面一定没有它。
对于下一次询问,删除这条边即可
- 如果不是割边,那么一定不选它,直接删除,减小求解的范围。
- 如果是割边,删除后也不会影响最大生成树的权值(删了可以缩小求解范围,使得下一条比他小的边一定在最大生成树里面)
对于2m次询问内容:
使用m次询问所有的边的长度
使用1次询问整个图的最大生成树
使用m-1次缩小范围。
最小的一条边一定在最小生成树里面。
代码
#include <bits/stdc++.h>
using namespace std;
priority_queue<pair<int, int> > pq;
int n, m;
int edge[600];
void ask(int k, bool tag)
{
printf("? ");
for(int i = 1; i <= k-1; i++)
{
if(tag) putchar('0');
else putchar('1');
}
if(tag) putchar('1');
else putchar('0');
for(int i = k+1; i <= m; i++)
{
if(tag) putchar('0');
else putchar('1');
}
putchar('\n');
fflush(stdout);
}
void que()
{
printf("? ");
for(int i = 1; i <= m; i++)
{
printf("%d", edge[i]);
}
putchar('\n');
fflush(stdout);
}
int main()
{
int ans = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
int buf = 0;
ask(i, true);
scanf("%d", &buf);
pq.push(make_pair(buf, i));
}
for(int i = 1; i <= m; i++) edge[i] = 1;
que();
int res;
int last;
scanf("%d", &res);
last = res;
for(int i = 1; i <= m-1; i++)
{
pair<int, int>t;
t = pq.top();
pq.pop();
edge[t.second] = 0;
que();
scanf("%d", &res);
if(last - res < t.first);//并不需要干什么事情
else
{
ans += t.first;
}
last = res;
}
ans += pq.top().first;
printf("! ");
printf("%d", ans);
fflush(stdout);
return 0;
}
Codeforces Round #796 (Div. 2)(A~E题题解)的更多相关文章
- Codeforces Round #609 (Div. 2)前五题题解
Codeforces Round #609 (Div. 2)前五题题解 补题补题…… C题写挂了好几个次,最后一题看了好久题解才懂……我太迟钝了…… 然后因为longlong调了半个小时…… A.Eq ...
- Codeforces Round #599 (Div. 2)的简单题题解
难题不会啊…… 我感觉写这个的原因就是因为……无聊要给大家翻译题面 A. Maximum Square 简单题意: 有$n$条长为$a_i$,宽为1的木板,现在你可以随便抽几个拼在一起,然后你要从这一 ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) (前三题题解)
这场比赛好毒瘤哇,看第四题好像是中国人出的,怕不是dllxl出的. 第四道什么鬼,互动题不说,花了四十五分钟看懂题目,都想砸电脑了.然后发现不会,互动题从来没做过. 不过这次新号上蓝名了(我才不告诉你 ...
- BestCoder Round #11 (Div. 2) 前三题题解
题目链接: huangjing hdu5054 Alice and Bob 思路: 就是(x,y)在两个參考系中的表示演全然一样.那么仅仅可能在这个矩形的中点.. 题目: Alice and Bob ...
- Codeforces Round #310 (Div. 2)--A(简单题)
http://codeforces.com/problemset/problem/556/A 题意:给一个01字符串,把所有相邻的0和1去掉,问还剩下几个0和1. 题解:统计所有的0有多少个,1有多少 ...
- Codeforces Round #416 (Div. 2)(A,思维题,暴力,B,思维题,暴力)
A. Vladik and Courtesy time limit per test:2 seconds memory limit per test:256 megabytes input:stand ...
- Codeforces Round #336 (Div. 2)-608A.水题 608B.前缀和
A题和B题... A. Saitama Destroys Hotel time limit per test 1 second memory limit per test 256 megabyte ...
- Codeforces Round #316 (Div. 2) (ABC题)
A - Elections 题意: 每一场城市选举的结果,第一关键字是票数(降序),第二关键字是序号(升序),第一位获得胜利. 最后的选举结果,第一关键字是获胜城市数(降序),第二关键字是序号(升序) ...
- Codeforces Round #590 (Div. 3)【D题:26棵树状数组维护字符出现次数】
A题 题意:给你 n 个数 , 你需要改变这些数使得这 n 个数的值相等 , 并且要求改变后所有数的和需大于等于原来的所有数字的和 , 然后输出满足题意且改变后最小的数值. AC代码: #includ ...
随机推荐
- 审计 Linux 系统的操作行为的 5 种方案对比
点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 很多时候我们为了安全审计或者故障跟踪排错,可能会记录分析 ...
- CentOS 8 重启不能DHCP获取IP的解决方法
一个执着于技术的公众号 今天遇到一个神奇的现象,我对CentOS 8系统做初始化之后再重启系统,发现系统不能通过NetworkManager获取DHCP IP了 查了系统日志发现是: Apr 30 0 ...
- 馒头的1day漏洞巡舰系统
馒头的1day漏洞巡舰系统 1day漏洞巡舰系统的目的 1day漏洞巡舰系统的可行性 1day漏洞巡舰系统所用技术 1day漏洞巡舰系统思维导图 1day漏洞巡舰系统初步设计图 1day漏洞巡舰系统初 ...
- Docker部署mysql 5.7
Docker部署mysql 5.7 准备工作 在CentOS或者Linux创建部署目录,用于存放容器的配置和MySQL数据:目的是当重装或者升级容器时,配置文件和数据不会丢失.执行以下命令: a.创建 ...
- 将CSV格式或者EXCEL格式的文件导入到HIVE数据仓库中
学习内容:数据导入,要求将CSV格式或者EXCEL格式的文件导入到HIVE数据仓库中: ①hive建表:test1 create table test1 (InvoiceNo String, Stoc ...
- 单例模式与pickle模块
目录 设计模式之单例模式 pickle模块 设计模式之单例模式 设计模式是前辈们发明的经过反复验证用于解决固定问题的固定套路,在IT行业中设计模式总共有23种,可以分为三大类:创建型.结构型.行为型. ...
- 第06组Alpha冲刺(6/6)
目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2.曹兰英 3. 方梓涵 4.曾丽莉 5.鲍凌函 6.杜筱 7.黄少丹 8.詹鑫冰 9.董翔云 10.吴沅静 1.3 冲刺成果展示 1.1 基 ...
- 「VMware校园挑战赛」小V的和式
Description 给定 \(n,m\) ,求 \[\sum\limits_{x_1=1}^{n}\sum\limits_{x_2=1}^{n}\sum\limits_{y_1=1}^{m}\su ...
- 「洛谷 P3834」「模板」可持久化线段树 题解报告
题目描述 给定n个整数构成的序列,将对于指定的闭区间查询其区间内的第k小值. 输入输出格式 输入格式 第一行包含两个正整数n,m,分别表示序列的长度和查询的个数. 第二行包含n个整数,表示这个序列各项 ...
- 阶段性总结 GDOI 2022 PJ
阶段性总结 GDOI 2022 PJ 比赛经过 Day ? ~ Day -1 半停课集训,补了很多东西,但是之前漏得太多了,结果是还有很多题没改 打了若干场 AtCoder ,承认自己思维的不足,训练 ...

x5823