Codeforces Round #883 (Div. 3) A-G
A
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
bool solve() {
int n;
cin >> n;
int cnt = 0;
for (int i = 1;i <= n;i++) {
int a, b;
cin >> a >> b;
if (a > b) cnt++;
}
cout << cnt << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
B
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
char dt[4][4];
bool solve() {
for (int i = 1;i <= 3;i++)
for (int j = 1;j <= 3;j++)
cin >> dt[i][j];
for (int i = 1;i <= 3;i++) {
if (dt[i][1] == '.') continue;
bool ok = 1;
for (int j = 1;j <= 3;j++) ok &= dt[i][1] == dt[i][j];
if (ok) {
cout << dt[i][1] << '\n';
return true;
}
}
for (int j = 1;j <= 3;j++) {
if (dt[1][j] == '.') continue;
bool ok = 1;
for (int i = 1;i <= 3;i++) ok &= dt[1][j] == dt[i][j];
if (ok) {
cout << dt[1][j] << '\n';
return true;
}
}
if (dt[1][1] != '.') {
bool ok = 1;
for (int i = 1;i <= 3;i++) ok &= dt[1][1] == dt[i][i];
if (ok) {
cout << dt[1][1] << '\n';
return true;
}
}
if (dt[1][3] != '.') {
bool ok = 1;
for (int i = 1;i <= 3;i++) ok &= dt[1][3] == dt[i][3 - i + 1];
if (ok) {
cout << dt[1][3] << '\n';
return true;
}
}
return false;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << "DRAW" << '\n';
}
return 0;
}
C
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
pair<int, ll> res[200007];
bool solve() {
int n, m, h;
cin >> n >> m >> h;
for (int i = 1;i <= n;i++) {
priority_queue<int, vector<int>, greater<int>> pq;
for (int j = 1;j <= m;j++) {
int x;
cin >> x;
pq.push(x);
}
int sum = 0;
int point = 0;
ll penalty = 0;
while (pq.size()) {
int t = pq.top();
pq.pop();
if (sum + t > h) break;
sum += t;
point++;
penalty += sum;
}
res[i] = { point,penalty };
}
auto tar = res[1];
auto cmp = [&](pair<int, ll> a, pair<int, ll> b) {return a.first == b.first ? a.second<b.second : a.first>b.first;};
sort(res + 1, res + n + 1, cmp);
int id = lower_bound(res + 1, res + n + 1, tar, cmp) - res;
cout << id << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
D
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int y[200007] = { (int)2e9 };
bool solve() {
int n;
double d, h;
cin >> n >> d >> h;
for (int i = 1;i <= n;i++) cin >> y[i];
sort(y + 1, y + n + 1, greater<int>());
double ans = 0;
for (int i = 1;i <= n;i++) {
double delta = min(h, 0.0 + y[i - 1] - y[i]);
ans += (2 - delta / h) * d * delta / 2;
}
cout << fixed << setprecision(6) << ans << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
E
题意
给定一个 \(n\) ,问是否存在 \(k \geq 2 ,s \geq 2\) ,使得 \(\displaystyle n = \sum_{i=0}^s k^i\) 。
题解
方法一
知识点:数学,枚举。
实际上,\(\displaystyle k^s < \sum_{i=0}^s k^i < (k+1)^{s}\) ,因此一定有 \(\displaystyle\left\lfloor \sqrt[s]{\sum_{i=0}^s k^i} \right\rfloor = k\) 。
因此,我们枚举 \(s\) ,令 \(k = \left\lfloor \sqrt[s]{n} \right\rfloor\) ,然后验证这一对 \(s,k\) 。若 \(n\) 可行,那么一定有 \(\displaystyle \sum_{i=0}^s k^i = n\) 。
其中开根号用的是 pow
,这个函数精度很差,但是这里是没有问题的,因为上下界都离得很远。
时间复杂度 \(O(60)\)
空间复杂度 \(O(1)\)
方法二
知识点:数学,二分,枚举。
注意到, \(s\) 不会太大,最大只可能 \(60\) ,考虑枚举 \(s\) 。
对于一个 \(s\) ,由于 \(\displaystyle \sum_{i=0}^s k^i\) 是关于 \(k\) 单调的,我们可以二分 \(k\) ,找到使得 \(\displaystyle \sum_{i=0}^s k^i\) 小于等于 \(n\) 的最后一个 \(k\) ,随后验证这个 \(k\) 是否是答案即可。
注意到, \(k\) 也不会超过 \(10^9\) ,这个结论能降低常数。
时间复杂度 \(O(60 \times \log 10^9)\)
空间复杂度 \(O(1)\)
方法三
知识点:数学,二分,枚举。
对于 \(s \geq 3\) 的情况, \(k\) 不会超过 \(10^6\) ,因此可以枚举 \(k \leq 10^6\) ,对每个 \(k\) 预处理出 \(s \in[3,60]\) 的所有答案。
对于 \(s = 2\) 的情况,和方法一一样直接二分即可。
时间复杂度 \(\displaystyle O\left( \left(\sum_{k=2}^{10^6}\log_k 10^{18}\right) \cdot \log \left(\sum_{k=2}^{10^6}\log_k 10^{18}\right) + \log 10^9 \right)\)
空间复杂度 \(\displaystyle O\left(\sum_{k=2}^{10^6}\log_k 10^{18}\right)\)
代码
方法一
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128_t;
i128 qpow(i128 a, ll k) {
i128 ans = 1;
while (k) {
if (k & 1) ans *= a;
k >>= 1;
a *= a;
}
return ans;
}
bool solve() {
ll n;
cin >> n;
for (int i = 2, k;(k = pow(n, 1.0 / i)) >= 2;i++) {
i128 res = (1 - qpow(k, i + 1)) / (1 - k);
if (res == n) {
cout << "YES" << '\n';
return true;
}
}
return false;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << "NO" << '\n';
}
return 0;
}
方法二
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 2e18;
ll calc(int x, int s) {
ll sum = 0;
__int128_t mul = 1;
for (int i = 0;i <= s;i++) {
if (sum + mul > INF) return INF;
sum += mul;
mul *= x;
}
return sum;
}
bool solve() {
ll n;
cin >> n;
for (int i = 2;i <= 60;i++) {
int l = 2, r = 1e9;
while (l <= r) {
int mid = l + r >> 1;
if (calc(mid, i) <= n) l = mid + 1;
else r = mid - 1;
}
if (r >= 2 && calc(r, i) == n) {
cout << "YES" << '\n';
return true;
}
}
return false;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << "NO" << '\n';
}
return 0;
}
方法三
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1e18;
set<ll> st;
void init() {
for (int i = 2;i <= 1000000;i++) {
ll sum = 1 + i + 1LL * i * i;
while (1 + (__int128_t)sum * i <= INF) {
sum = 1 + sum * i;
st.insert(sum);
}
}
}
ll calc(int x) {
return 1 + x + 1LL * x * x;
}
bool solve() {
ll n;
cin >> n;
if (st.count(n)) {
cout << "YES" << '\n';
return true;
}
int l = 2, r = 1e9;
while (l <= r) {
int mid = l + r >> 1;
if (calc(mid) <= n) l = mid + 1;
else r = mid - 1;
}
if (r >= 2 && calc(r) == n) {
cout << "YES" << '\n';
return true;
}
return false;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
init();
while (t--) {
if (!solve()) cout << "NO" << '\n';
}
return 0;
}
F
题意
房间里有 \(n\) 个物品,每个物品的种类为 \(a_i\) 。这些物品中,有一个是模仿者伪装的。
现在可以进行一场最多 \(5\) 轮的实验去找出它,每一轮按顺序发生如下事件:
- 记录当前房间内的所有物品的种类。
- 可指出一个物品确定是伪装的,则试验结束。但这个操作只能执行一次,若不确定,则要做下一步操作。
- 选出一些物品移出房间(可以不选,但模仿者始终不会被移出房间)并离开房间。随后房间里的物品会被打乱,模仿者也可以转换成别的物品(即使房间里不存在的物品)。
- 进入房间,继续下一轮。模仿者可能不转变,但最多保持两轮是同一个类型的物品。
给出操作,找到模仿者。
题解
知识点:枚举。
一开始可以不移出物品,这样若模仿者发生变化,则最多两轮一定有一个类型的物品多了一个。
移出除了多出来物品的类型以外类型的所有物品。
剩下的一定是包括模仿者的同一类型的物品,再最多不超过一轮,一定会出现一个不同类型的物品,就是模仿者。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int n;
int a[207];
int cnt1[10], cnt2[10];
void query(const vector<int> &del) {
cout << "- " << del.size() << " ";
for (auto x : del) cout << x << " ";
cout << endl;
n -= del.size();
for (int i = 1;i <= n;i++) cin >> a[i];
}
void answer(int x) {
cout << "! " << x << endl;
}
bool solve() {
for (int i = 1;i <= 9;i++) cnt1[i] = cnt2[i] = 0;
cin >> n;
for (int i = 1;i <= n;i++) cin >> a[i], cnt1[a[i]]++;
query({});
for (int i = 1;i <= n;i++) cnt2[a[i]]++;
int type = 0;
for (int i = 1;i <= 9;i++) {
if (cnt1[i] < cnt2[i]) {
type = i;
break;
}
}
if (!type) {
for (int i = 1;i <= 9;i++) cnt2[i] = 0;
query({});
for (int i = 1;i <= n;i++) cnt2[a[i]]++;
for (int i = 1;i <= 9;i++) {
if (cnt1[i] < cnt2[i]) {
type = i;
break;
}
}
}
vector<int> del;
for (int i = 1;i <= n;i++) if (a[i] != type) del.push_back(i);
query(del);
bool ok = 0;
for (int i = 1;i <= n;i++) {
if (a[i] != type) {
answer(i);
ok = 1;
break;
}
}
if (!ok) {
query({});
for (int i = 1;i <= n;i++) {
if (a[i] != type) {
answer(i);
ok = 1;
break;
}
}
}
return true;
}
int main() {
//std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
G
题意
有 \(n\) 种症状和 \(m\) 个药品,症状的情况通过一个长为 \(n\) 的 \(01\) 串给出。
每种药品治疗效果是可以使特定的一些症状消失,但副作用是使得特定的症状出现。
每种药有一个疗程 \(d\) ,疗程之内不允许使用其他药。
现在给出初始症状情况,问最少需要多少天才能使得症状全部消失。
题解
知识点:最短路,状压dp,拓扑序dp。
考虑状压,将症状压缩为一个整数。
随后,我们将 \(2^n\) 种症状情况看作点, \(m\) 种药看作边。显然,每个点都可以有 \(m\) 条出边。
假设当前的症状是 \(st\) ,将要使用的药品的效果是 \(e\) ,副作用是 \(se\) ,那么使用后的症状为 (st & ~e) | se
,这样就构建了一条边,权值为疗程时间。
问题就变成,从初始状态到 \(0\) 状态的最短路,直接跑最短路即可。
求最短路的本质就是在最短路图这个DAG上进行拓扑序dp,因此一些dp可以考虑抽象成图的形式跑最短路。
时间复杂度 \(O(m2^n \log (m2^n))\)
空间复杂度 \(O(2^n + m)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m;
int d[1007], e[1007], se[1007];
bool vis[1 << 10 + 1];
int dis[1 << 10 + 1];
struct node {
int v, w;
friend bool operator<(const node &a, const node &b) { return a.w > b.w; }
};
priority_queue<node> pq;
void dijkstra(int st) {
for (int i = 0;i < (1 << n);i++) dis[i] = 1e9, vis[i] = 0;
dis[st] = 0;
pq.push({ st,0 });
while (!pq.empty()) {
int u = pq.top().v;
pq.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = 1;i <= m;i++) {
int v = (u & ~e[i]) | se[i];
int w = d[i];
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
pq.push({ v,dis[v] });
}
}
}
}
bool solve() {
cin >> n >> m;
int st = 0;
for (int i = 0;i < n;i++) {
char ch;
cin >> ch;
st |= (ch == '1') << i;
}
for (int i = 1;i <= m;i++) {
cin >> d[i];
e[i] = 0, se[i] = 0;
for (int j = 0;j < n;j++) {
char ch;
cin >> ch;
e[i] |= (ch == '1') << j;
}
for (int j = 0;j < n;j++) {
char ch;
cin >> ch;
se[i] |= (ch == '1') << j;
}
}
dijkstra(st);
cout << (dis[0] >= 1e9 ? -1 : dis[0]) << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
Codeforces Round #883 (Div. 3) A-G的更多相关文章
- Educational Codeforces Round 47 (Div 2) (A~G)
目录 Codeforces 1009 A.Game Shopping B.Minimum Ternary String C.Annoying Present D.Relatively Prime Gr ...
- Educational Codeforces Round 46 (Div 2) (A~G)
目录 Codeforces 1000 A.Codehorses T-shirts B.Light It Up C.Covered Points Count(差分) D.Yet Another Prob ...
- Educational Codeforces Round 45 (Div 2) (A~G)
目录 Codeforces 990 A.Commentary Boxes B.Micro-World C.Bracket Sequences Concatenation Problem D.Graph ...
- Codeforces Round #582 (Div. 3)-G. Path Queries-并查集
Codeforces Round #582 (Div. 3)-G. Path Queries-并查集 [Problem Description] 给你一棵树,求有多少条简单路径\((u,v)\),满足 ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts
题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...
- Codeforces Round #383 (Div. 2) 题解【ABCDE】
Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...
- 模拟 Codeforces Round #249 (Div. 2) C. Cardiogram
题目地址:http://codeforces.com/contest/435/problem/C /* 题意:给一组公式,一组数据,计算得到一系列的坐标点,画出折线图:) 模拟题:蛮恶心的,不过也简单 ...
- Codeforces Round #368 (Div. 2) B. Bakery (模拟)
Bakery 题目链接: http://codeforces.com/contest/707/problem/B Description Masha wants to open her own bak ...
随机推荐
- CommunityToolkit.Mvvm8.1 消息通知(4)
本系列文章导航 https://www.cnblogs.com/aierong/p/17300066.html https://github.com/aierong/WpfDemo (自我Demo地址 ...
- 【SpringMVC】(一)
SpringMVC简介 SpringMVC是Spring的一个后续产品,是Spring的一个子项目 基于原生的Servlet,通过了功能强大的DispatcherServlet,对请求和响应进行统一处 ...
- MySQL MHA信息的收集【Filebeat+logstash+MySQL】
一.项目背景 随着集团MHA集群的日渐增长,MHA管理平台话越来越迫切.而MHA平台的建设第一步就是将这些成百上千套的MHA集群信息收集起来,便于查询和管理. MHA主要信息如下: (1)基础配置信息 ...
- APISIX 是怎么保护用户的敏感数据不被泄露的?
本文以 APISIX 作为例子,为大家介绍了如何借助 Global Data Encryption 功能来保护敏感数据,确保不会有任何敏感数据进行明文存储,这样即使 etcd 中所有存储的数据都被盗取 ...
- VUE3企业级项目基础框架搭建流程(3)
VUE-Router npm install vue-router@4 安装完成后,在项目目录里新建一个router文件,我这里的用的是typeScript,所以建立的是router.ts, 该文件是 ...
- Rust中的宏:声明宏和过程宏
Rust中的声明宏和过程宏 宏是Rust语言中的一个重要特性,它允许开发人员编写可重用的代码,以便在编译时扩展和生成新的代码.宏可以帮助开发人员减少重复代码,并提高代码的可读性和可维护性.Rust中有 ...
- Mysql中如果建立了索引,索引所占的空间随着数据量增长而变大,这样无论写入还是查询,性能都会有所下降,怎么处理?
索引所占空间的增长确实会对MySQL数据库的写入性能和查询性能造成影响,这主要是由于索引数据过多时会导致磁盘I/O操作变得非常频繁,从而使性能下降.为此,可以采取以下几种方式来减缓这种影响: 1. 限 ...
- 聊聊开关和CPU之间故事
目录 开关 电报和继电器 门电路 材料学的发展 继电器与哈佛Mark1号 真空管与巨人一号 晶体管与IBM608 计算机2大特性:计算能力和记忆能力 作者:小牛呼噜噜 | https://xiaoni ...
- ChatGPT Plugin 插件开发:基于 ASP.NET Core Minimal API
前言 这是一篇ChatGPT插件开发教程,描述如何使用 ASP.NET Core Minimal API 开发 ChatGPT 插件,以最简单的 Todo List 指导示例作为入门教程. 这个Tod ...
- 2022-08-24:给定一个长度为3N的数组,其中最多含有0、1、2三种值, 你可以把任何一个连续区间上的数组,全变成0、1、2中的一种, 目的是让0、1、2三种数字的个数都是N。 返回最小的变化次
2022-08-24:给定一个长度为3N的数组,其中最多含有0.1.2三种值, 你可以把任何一个连续区间上的数组,全变成0.1.2中的一种, 目的是让0.1.2三种数字的个数都是N. 返回最小的变化次 ...