Codeforces Round #618 (Div. 2)
Posted heyuhhh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #618 (Div. 2)相关的知识,希望对你有一定的参考价值。
A. Non-zero
签到。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/9 22:07:26
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 100 + 5;
int n;
int a[N];
void run(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
int sum = 0, ans = 0;
for(int i = 1; i <= n; i++) {
if(a[i] == 0) ++ans, ++a[i];
sum += a[i];
}
if(sum == 0) {
for(int i = 1; i <= n; i++) {
if(a[i] != -1) {
cout << ans + 1 << '
';
return;
}
}
cout << ans + 2 << '
';
} else cout << ans << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
B. Assigning to Classes
贪心即可。
我们选出的两个数中,假设在左边的为(a),右边的为(b),那么小于(a)的有(x)个,大于(a)的有(x)个;同理小于(b)和大于(b)的都有(y)个。那么左侧为(x+y)个,右侧为(x+y)个。
所以推出最后选出的(a,b)位置是对称的,因为选最中间的两个即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/9 22:17:29
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
int n;
int a[N];
void run(){
cin >> n;
n *= 2;
for(int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
cout << a[n / 2 + 1] - a[n / 2] << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
C. Anu Has a Function
题意:
定义(f(x,y)=(x|y)-y)。
先给出序列(a),现在可以重新排列(a)的顺序,问最终(f(f(cdots f(f(a_1,a_2), a_3),cdots a_{n-1}),a_n))最大为多少。
思路:
从(f)的表达式中可以知道,(f(x,y))的含义为:(x)的二进制位中,若某个二进制位为(1)且(y)在这位也为(1),那么这位就变为(0)。
然后我们按二进制位来分析,假设我们钦定了(a_1),若二进制第(k)位只有(a_1)才为(1),那么显然后面无论怎么安排,这位都将保留在答案中;否则,无论后面怎么安排,这位必然会被另一个(a_i)抵消。
因为要使得答案最大,我们贪心得选择(a_1)即可,选定之后,后面无论怎么安排,答案都唯一。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/9 22:24:07
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int n;
int a[N];
bool chk[N];
void run(){
for(int i = 1; i <= n; i++) cin >> a[i];
vector <int> v[31];
for(int i = 30; i >= 0; i--) {
for(int j = 1; j <= n; j++) {
if(a[j] >> i & 1) {
v[i].push_back(j);
}
}
if(sz(v[i]) == 1) {
chk[v[i][0]] = true;
break;
}
}
for(int i = 1; i <= n; i++) if(chk[i]) cout << a[i] << ' ';
for(int i = 1; i <= n; i++) if(!chk[i]) cout << a[i] << ' ';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
D. Aerodynamic
题意:
给出一个凸多边形,现在将其平移且保证原点被包含在凸多边形内部(包括边缘)。
最终画出的图形的并集也是一个凸多边形。
问这两个凸多边形是否相似。
思路:
观察样例得到一个结论:
若凸多边形关于重心对称,则最终是相似的。
至于证明并不会。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/9 23:14:21
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int n;
int x[N], y[N];
void run(){
for(int i = 1; i <= n; i++) {
cin >> x[i] >> y[i];
}
x[n + 1] = x[1], y[n + 1] = y[1];
if(n & 1) {
cout << "NO" << '
';
return;
}
for(int i = 1; i <= n / 2; i++) {
int j = i + n / 2;
if(x[i + 1] - x[i] == x[j] - x[j + 1] && y[i + 1] - y[i] == y[j] - y[j + 1]) {}
else {
cout << "NO" << '
';
return;
}
}
cout << "YES" << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
E. Water Balance
题意:
给出数组(a),现在可以执行任意次如下操作:
- 选择一段区间(displaystyle [l,r]),将(displaystyle a_l,a_{l+1},cdots,a_r)变为(displaystyle frac{a_l+a_{l+1}+cdots+a_r}{r-l+1})。
现在问最终字典序最小的(a)为多少。
思路:
首先容易得到一个结论,最终选择的区间一定是一段一段的,不会产生区间覆盖的情况,可以区间覆盖就可以将区间合并。
记(pre_i)为数组(a)的前缀和,那么由(displaystyle frac{pre_r-pre_{l-1}}{r-(l-1)})这样的形式我们可以联想到斜率。
现在二维平面坐标系中有(n+1)个点,分别为((0,0),(1,pre_1),cdots,(n,pre_n)),那么现在我们的任务就是:从((0,0))出发,找到使得斜率最小的点((i,pre_i)),然后从((i,pre_i))出发...以此类推。
那么我们只需要用单调栈维护一个下凸壳就行,下凸壳有个很良好的性质,就是对于凸壳上的任意一条边((i,j)),不存在(t,t
ot ={i,j}),使得(k_{ij}>k_{it})。
代码如下:
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/9 22:49:45
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '
'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e6 + 5;
int n;
int a[N];
double b[N];
ll pre[N];
int q[N];
void run(){
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + a[i];
}
int top = 0;
for(int i = 0; i <= n; i++) {
if(top <= 1) {
q[++top] = i;
continue;
}
while(top > 1 && 1ll * (pre[q[top]] - pre[q[top - 1]]) * (i - q[top]) >= 1ll * (pre[i] - pre[q[top]]) * (q[top] - q[top - 1])) {
--top;
}
q[++top] = i;
}
for(int i = 1; i < top; i++) {
double x = 1.0 * (pre[q[i + 1]] - pre[q[i]]) / (q[i + 1] - q[i]);
for(int j = q[i] + 1; j <= q[i + 1]; j++) b[j] = x;
}
for(int i = 1; i <= n; i++) cout << b[i] << '
';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
以上是关于Codeforces Round #618 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #618 (Div. 2)
Codeforces Round #618 (Div. 2)
Codeforces Round #618 (Div. 2)
Codeforces Round #618 (Div. 2)题解