目录
比赛链接
Dashboard - Codeforces Round 891 (Div. 3) - Codeforces
A. Array Coloring
思路
数组中奇数出现的次数是奇数则输出NO,反之输出YES
代码
#include<bits/stdc++.h>
#define int long long
#define TEST int T; cin >> T; while (T--)
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const int N = 1e6 + 30;
const int M = 1e3 + 10;
const int inf = 512785182741247112;
const int mod = 100003;
using namespace std;
void solve() {
int n;
cin >> n;
int c1 = 0, c2 = 0;
for (int i = 1, x; i <= n; i++)
{
cin >> x;
if (x & 1) c1++;
else c2++;
}
if (c1 & 1) cout << "NO\n";
else cout << "YES\n";
}
signed main() {
ios;
TEST
solve();
return 0;
}
B. Maximum Rounding
思路
按照题目要求,我们找到最右边大于5的数的位置,将这个位置右边的数全设置为0,这个位置的下一个位置+1,再加点优化处理。
代码
#include<bits/stdc++.h>
#define int long long
#define TEST int T; cin >> T; while (T--)
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const int N = 1e6 + 30;
const int M = 1e3 + 10;
const int inf = 512785182741247112;
const int mod = 100003;
using namespace std;
void solve() {
string s;
cin >> s;
vector<int>num(s.size() + 3);
int n = s.size();
for (int i = 0; i<n; i++)
{
num[i+1] = s[i] - '0';
}
int pos = -1;
for (int i = n; i >= 1; i--)
{
if (num[i] >= 5)
{
num[i - 1]++;
pos = i;
}
}
for (int i = 0; i <= n; i++)
{
if (i == 0 && num[i] == 0) continue;
if (i >= pos&&pos!=-1) cout << 0;
else cout << num[i];
}
cout << "\n";
}
signed main() {
ios;
TEST
solve();
return 0;
}
C. Assembly via Minimums
思路
先将数组按照从小到大排序,然后反推查找答案即可,既然我们需要的是i和j的最小值,那么我们在设置答案数组的时候给他们两个都设置成一样的即可。
代码
#include<bits/stdc++.h>
#define int long long
#define TEST int T; cin >> T; while (T--)
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const int N = 1e6 + 30;
const int M = 1e3 + 10;
const int inf = 512785182741247112;
const int mod = 100003;
using namespace std;
void solve() {
int n;
cin >> n;
vector<int>a(n * (n - 1) / 2 + 1);
for (int i = 1; i <= n * (n - 1) / 2; i++)
{
cin >> a[i];
}
sort(a.begin()+1, a.end());
vector<int>ans(n + 1);
int cnt = 0;
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
++cnt;
ans[i] = ans[j] = a[cnt];
}
}
for (int i = 1; i <= n; i++) cout << ans[i] << ' ';
cout << "\n";
}
signed main() {
ios;
TEST
solve();
return 0;
}
D. Strong Vertices
思路
其中如果 au−av≥bu−bv,au−av≥bu−bv 存在从 u 到 v ( u≠v ) 的边。
我们把公式转变一下,au-bu<=av-bv时,我们就可以建边u到v,我们需要的是一个连接其余所有点的点,发现他们必须要建(n-1)条边,所以我们直接构造数组c[i]=a[i]-b[i],将c[i]排序后,找到最大的数(同大可以),为了按照顺序输出,我们需要离散化处理一下。
代码
#include<bits/stdc++.h>
#define int long long
#define TEST int T; cin >> T; while (T--)
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const int N = 2e5 + 30;
const int M = 1e3 + 10;
const int inf = 512785182741247112;
const int mod = 100003;
using namespace std;
int a[N], b[N];
struct node
{
int va, id;
}e[N];
bool cmp(node a, node b)
{
if (a.va == b.va) return a.id < b.id;
return a.va > b.va;
}
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
for (int i = 1; i <= n; i++)
{
e[i].va = a[i] - b[i];
e[i].id = i;
}
sort(e + 1, e + 1 + n, cmp);
vector<int>ans;
int mx = e[1].va;
for (int i = 1; i <= n; i++)
{
if (e[i].va == mx) ans.push_back(e[i].id);
else break;
}
sort(ans.begin(), ans.end());
cout << ans.size() << "\n";
for (auto x : ans) cout << x << ' ';
cout << "\n";
}
signed main() {
ios;
TEST
solve();
return 0;
}
E. Power of Points
思路
我们先将数组排序,再求差值,我们模拟一下,从1开始,我们对1到2的使用就是(n-1)*(a2-a1),后面再从2开始,找到规律就行了。
代码
#include<bits/stdc++.h>
#define int long long
#define TEST int T; cin >> T; while (T--)
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const int N = 2e5 + 30;
const int M = 1e3 + 10;
const int inf = 512785182741247112;
const int mod = 100003;
using namespace std;
struct node
{
int a, id;
}e[N];
bool cmp(node a, node b)
{
if (a.a == b.a) return a.id < b.id;
else return a.a < b.a;
}
int b[N];
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> e[i].a;
e[i].id = i;
}
sort(e + 1, e + 1 + n,cmp);
vector<int>ans(n + 1, n);
for (int i = 2; i <= n; i++)
{
b[i - 1] = e[i].a - e[i - 1].a;
}
int cnt = 0;
for (int i = 1; i < n; i++)
{
cnt += (n - i) * b[i];
}
ans[1] += cnt;
int pre = 2 - n;
for (int i = 1; i < n; i++)
{
cnt += (b[i]) * pre;
ans[i + 1] += cnt;
pre += 2;
}
vector<int>res(n + 1);
for (int i = 1; i <= n; i++)
{
res[e[i].id] = ans[i];
}
for (int i = 1; i <= n; i++) cout << res[i] << ' ';
cout << "\n";
}
signed main() {
ios;
TEST
solve();
return 0;
}
F. Sum and Product
思路
我们给出x,y需要找到两个元素a,b满足a+b=x,a*b=y,我们就可以得到x^2-bx+c=0,我们要找的两个元素就是这个方程的两个解,按照公式找到这两个解即可,后面在看这个解在数组中出现的次数,我们在询问之前可以用map从下每个元素出现的次数。
代码
#include<bits/stdc++.h>
#define int long long
#define TEST int T; cin >> T; while (T--)
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const int N = 2e5 + 30;
const int M = 1e3 + 10;
const int inf = 512785182741247112;
const int mod = 100003;
using namespace std;
int judge(int d)
{
int k = (int)sqrt(d);
if (k * k == d) return true;
return false;
}
void solve() {
int n;
cin >> n;
map<int, int>q;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
q[x]++;
}
int t;
cin >> t;
while (t--)
{
int x, y;
cin >> x >> y;
int D = x * x - 4 * y;//D必须是完全平方数
if (!judge(D))
{
cout << "0\n";
continue;
}
bool ok = false;
if ((int)(x - sqrt(D)) % 2 != 0 || (int)(x + sqrt(D)) % 2 != 0)
{
ok = true;
}
if (ok)
{
cout << "0\n";
continue;
}
int x1 = (x - sqrt(D)) / 2;
int x2 = (x + sqrt(D)) / 2;
if (D > 0)
{
if (q[x1] && q[x2])
cout << q[x1] * q[x2] << "\n";
else cout << "0\n";
}
else if (D == 0)
{
if (q[x1])
cout << (q[x1] - 1) * q[x1] / 2 << "\n";
else cout << "0\n";
}
else
{
cout << "0\n";
}
}
}
signed main() {
ios;
TEST
solve();
return 0;
}