Codeforces Round #660 (Div. 2) A、B、C题解
A. Captain Flint and Crew Recruitment #构造
题目链接
题意
定义一类正整数,能够被\(p*q\)表示,其中\(p、q(1<p<q)\)均为素数,称之为\(nearly\ prime\) 。现要求判断整数\(n\),是否能被4个不同整数之和表示,且其中至少三个整数为\(nearly\ prime\) (是则,输出YES否则输出NO)
分析
\(n = 31 = 2\times7+2\times5+2\times3+1\),其中\(14,10,6\)为\(nearly\ prime\)
\(n = 32 = 2\times3+2\times5+2\times7+2\),其中\(14,10,6\)为\(nearly\ prime\)
容易得到最小的三个\(nearly\ prime\)为\(6,10,14\),因而满足条件的最小整数为31,见上。当\(n\leq30=6+10+14\),答案NO。当\(n>30\),答案定为YES
难道剩余的正整数都能被\(6,10,14,n-30\)表示吗?注意,当\(n-30 = 6or10or14\)时,出现了重复数字,我们可以构造出比{\(2*3,2*5,2*7,n\)}稍大的组合,即{\(2*3,2*5,3*5,n\)}
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
int main() {
int Q; scanf("%d", &Q);
while (Q--) {
int n;
scanf("%d", &n);
if (n <= 30) {
printf("NO\n");
continue;
}
int last = n - 30;
if (last == 6 || last == 10 || last == 14) {
printf("YES\n6 10 15 %d\n", n - 31);
}
else {
printf("YES\n6 10 14 %d\n", n - 30);
}
}
return 0;
}
B. Captain Flint and a Long Voyage #构造 #贪心
题目链接
题意
给定整数\(n\),找出一个十进制数字\(x\)满足:长度为\(n\),得到\(x\)在二进制下的串,去掉后面的\(n\)位,新二进制串是最大的,且数字\(x\)越小越好。好绕,原题面看得十分吃力
分析
我们将\([0, 9]\)数字分别转化为二进制串,可以观察到数字\(8,9\)的二进制串长度最长,分别为\(1000, 1001\),由题干要求,抹除\(n\)位后的二进制串最大,那么利用贪心思想,要找到这样的串,那么十进制数字\(x\)的二进制串越长越好,于是我们可以断定这个\(x\)肯定由\(8or9\)组成。
但别忘了题干还要求我们数字\(x\)越小越好,为什么可以有这样的条件?拿数字\(8,9\)的二进制串\(1000, 1001\)而言,当我们抹除最后1位时,得到的两个新串是相等的!于是但凡得到数字\(999...999\),我们可以在合法的长度内将末位的几个\(9\)替换为\(8\),这样既保证二进制串大且原十进制数小的情况了,即\(x\)的组成肯定为\(999...888\)。
如何确定这一合法的替换长度呢?考虑到8/9二进制串长度为4。对于原数字\(x\)最末尾的最末尾的(向上取整)\(n/4\)个要被去除的串,选8还是9的二进制串是没有区别的
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
int main(){
int Q; scanf("%d", &Q);
while(Q--){
int n;
scanf("%d", &n);
int len = n / 4; //将最后n位换成len个数字8的二进制串
if(n % 4 != 0) len++; //余数为[1, 3]说明还可以再替换多一个数字8的二进制串
for (int i = 1; i <= n - len; i++)
printf("9");
for (int i = 1; i <= len; i++)
printf("8");
printf("\n");
}
return 0;
}
C. Uncle Bogdan and Country Happiness #DFS #逆向思维
题目链接
题意
给定\(n\)个节点的树结构,\(m\)个人初始在根节点\(1\)号,已知每个人都有各自要到达的节点(默认走最短路),他们刚出发有各自的心情状态(好/坏)且我们未知,在节点之间的转移过程中好心情会转化为坏心情,但心情坏的不会发生改变。先给定每个节点数据h[i],理论上值为该节点上 心情好的人数 - 心情坏的人数,现要判断给定数据是否正确。
分析
若从节点1出发来考虑似乎不容易,我们可以尝试从每个到达的目标节点逆推到根节点。
设经过城市\(now\)人数有\(sum[now]\),该城市理论快乐指数为\(h[now]\),可以计算出理论上该城市的快乐人数
\(Hapsum[now] =(sum[now]+h[now])/2\)
\(= (Hapsum[now]+badsum[now]+Hapsum[now]-badsum[now])\)
参考官方题解,我们有三个标准去衡量数据的合法性:
- \(sum[now]+h[now]\)一定能被整除
- \(0\leq Hapsum[now]\leq sum[now]\) 即快乐人数肯定不会超过总人数
- \(Hapsum[to_1]+Hapsum[to_2]+...+Hapsum[to_{k}]\leq Hapsum[now]\) 即每个人从now出发可能会心情变糟,因而子节点的快乐人数总数一定不超过父节点
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 5;
struct Edge {
int to, nextNbr;
}E[MAXN << 1];
int Head[MAXN], tot = 0;
void addEdge(int u, int v) {
tot++;
E[tot].to = v; E[tot].nextNbr = Head[u]; Head[u] = tot;
}
int n, m, delt[MAXN], cnt[MAXN], sum[MAXN], HapSum[MAXN];
bool f = true;
void dfs(int pre, int now) {
if (f == false) return;
sum[now] = cnt[now];
int tmp_sum = 0;
for (int i = Head[now]; i >= 0; i = E[i].nextNbr) {
int v = E[i].to;
if (v != pre) {
dfs(now, v);
sum[now] += sum[v];
tmp_sum += HapSum[v]; //统计 快乐人数
}
} //sum[now]统计now节点为根的子树的总人数
if ((sum[now] + delt[now]) % 2 != 0) f = false; //说明不是整数...case1
HapSum[now] = (sum[now] + delt[now]) >> 1; //利用给定数据算出经过该城市后的理论快乐人数
if (HapSum[now] < 0 || HapSum[now] > sum[now]) f = false;//说明快乐人数比总人数还多...case2
if (HapSum[now] < tmp_sum) f = false;
//说明经过now城市后的快乐人数 竟然比 走得更远的城市的快乐人数 还 少...case3
}
int main() {
int Q; scanf("%d", &Q);
while (Q--) {
scanf("%d%d", &n, &m);
tot = 0; f = true;
for (int i = 1; i <= n; i++) scanf("%d", &cnt[i]);
for (int i = 1; i <= n; i++) scanf("%d", &delt[i]), Head[i] = -1;
for (int i = 1; i <= n - 1; i++) {
int x, y; scanf("%d%d", &x, &y);
addEdge(x, y); addEdge(y, x);
}
dfs(0, 1);
printf("%s\n", f ? "YES" : "NO");
}
return 0;
}
Codeforces Round #660 (Div. 2) A、B、C题解的更多相关文章
- Codeforces Round #609 (Div. 2)前五题题解
Codeforces Round #609 (Div. 2)前五题题解 补题补题…… C题写挂了好几个次,最后一题看了好久题解才懂……我太迟钝了…… 然后因为longlong调了半个小时…… A.Eq ...
- Codeforces Round #660 (Div. 2) Captain Flint and Treasure 拓扑排序(按照出度、入读两边拓扑排序)
题目链接:Captain Flint and Treasure 题意: 一种操作为 选一个下标 使得ans+=a[i] 且 把a[b[i]]+a[i] 要求每个下标都进行一种这样的操作,问怎么样的 ...
- Codeforces Round #660 (Div. 2) Uncle Bogdan and Country Happiness dfs
题目链接:Uncle Bogdan and Country Happiness 题意: t组输入,每组数据输入如下 首先一个n代表有n个城市,所有城市总人数为m,后面输入pi表示第i个城市的居住人数, ...
- Codeforces Round #660 (Div. 2) A. Captain Flint and Crew Recruitment、Captain Flint and a Long Voyage
题目链接:Captain Flint and Crew Recruitment 题意: t组输入,每一组输入一个n.这里我们说一下题目定义的近似质数概念: "如果可以将正整数x表示为p⋅q, ...
- Codeforces Round #660 (Div. 2) C. Uncle Bogdan and Country Happiness (DFS)
题意:有\(n\)个人,每个人居住在某个节点,所有人都在节点\(1\)上班,下班后沿着最短路径回家,在回家途中心情可能会变差(心情只会变差不会变好),每个节点都有一个开心值,开心值等于所有经过时的好心 ...
- Codeforces Round #660 (Div. 2)
A. Captain Flint and Crew Recruitment 题意:定义了一种数(接近质数),这种数可以写成p*q并且p和q都是素数,问n是否可以写成四个不同的数的和,并且保证至少三个数 ...
- Codeforces Round #556 (Div. 2) D. Three Religions 题解 动态规划
题目链接:http://codeforces.com/contest/1150/problem/D 题目大意: 你有一个参考串 s 和三个装载字符串的容器 vec[0..2] ,然后还有 q 次操作, ...
- Codeforces Round #604 (Div. 2) E. Beautiful Mirrors 题解 组合数学
题目链接:https://codeforces.com/contest/1265/problem/E 题目大意: 有 \(n\) 个步骤,第 \(i\) 个步骤成功的概率是 \(P_i\) ,每一步只 ...
- Codeforces Round #624 (Div. 3) F. Moving Points 题解
第一次写博客 ,请多指教! 翻了翻前面的题解发现都是用树状数组来做,这里更新一个 线段树+离散化的做法: 其实这道题是没有必要用线段树的,树状数组就能够解决.但是个人感觉把线段树用熟了会比树状数组更有 ...
随机推荐
- 一个Task.Factory.StartNew的错误用法
同事写了这样一段代码: FactoryStartNew类: using System; using System.Collections.Generic; using System.Linq; usi ...
- 关于ansible命令的执行过程
首先说明一下.每一个模块.都是有相应的.py文件的,可以通过rpm -ql ansible看到 要观察模块执行过程,可以在ansible命令执行时加上-v或-vvv,或者-vvvv看得更加详细 ans ...
- CF1336 Linova and Kingdom
题面 给定 n 个节点的有根树,根是 1 号节点. 你可以选择 k 个节点将其设置为工业城市,其余设置为旅游城市. 对于一个工业城市,定义它的幸福值为工业城市到根的路径经过的旅游城市的数量. 你需要求 ...
- 4G工业路由器的传输功率是越高越好吗?
现在人们越来越多的利用运营商网络进行家庭的Wi-Fi上网,早已是非常普遍的事情了.而无线路由器作为设备组网的重要组成部分,与路由器相关的话题.知识总会能够引发大家的热议.这里,以众山物联网研发.生产的 ...
- Django之实现分页显示内容
关注公众号"轻松学编程"了解更多.- 分页 1.作用 数据加载优化 2.前端引入bootstrap样式: {# 引入bootstrap样式的cdn资源 #} <link ...
- nextInt()和nextLine()连用报错
当nextInt(),next(),nextDouble(),nextFloat()方法与nextLine()连用并放在nextLine()前面时,会出现下面的错误: Exception in thr ...
- 响应式编程简介之:Reactor
目录 简介 Reactor简介 reactive programming的发展史 Iterable-Iterator 和Publisher-Subscriber的区别 为什么要使用异步reactive ...
- 分享JDK解压版(ZIP)
目录 由于安装版本的jdk不太方便,所以我分享一下如何去获取解压版的jdk,jdk配置的话看这个文章 一.先下载exe版本的jdk安装程序: 二.使用7-ZIP解压工具 2.1 JDK8的解压目录 2 ...
- EntityFramework Core上下文实例池原理分析
前言 无论是在我个人博客还是著作中,对于上下文实例池都只是通过大量文字描述来讲解其基本原理,而且也是浅尝辄止,导致我们对其认识仍是一知半解,本文我们摆源码,从源头开始分析.希望通过本文从源码的分析,我 ...
- ABP框架中一对多,多对多关系的处理以及功能界面的处理(1)
在我们开发业务的时候,一般数据库表都有相关的关系,除了单独表外,一般还包括一对多.多对多等常见的关系,在实际开发过程中,需要结合系统框架做对应的处理,本篇随笔介绍基于ABP框架对EF实体.DTO关系的 ...