A![](https://i-blog.csdnimg.cn/blog_migrate/5832746027ce7f6b1d8d683de0052fef.png)
题意:
在序列到
上定义“好对”(i, j)为对于任意
(
)都有|
-
| - |
-
| = |
-
|
思路:
易知取最大最小值下标即可,min/max_element方便好用
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#ifdef LOCAL
template<class t,class u>ostream& operator<<(ostream& os,const pair<t,u>& p){return os<<"("<<p.first<<","<<p.second<<")";}
template<class t>ostream& operator<<(ostream& os,const vector<t>& v){os<<"{"; for(auto e:v)os<<e<<","; return os<<"}";}
#endif
int n, m, t, k, a, b, c, d, cnt, mark, an, oT_To, x, y, z, ans;
int num[100005];
void solve() {
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> num[i];
}
cout << min_element(num, num+n) - num+1 << ' ' << max_element(num, num+n) - num+1 << '\n';
}
int main () {
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
oT_To = 1;
cin >> oT_To;
while (oT_To--) {
solve();
}
}
B
题意:
给出n个数,每次删除其中的任意一个数,然后将剩下的每个数减去这个数,重复操作至只剩下一个数为止,问剩下的数是否可能等于k
思路:
减去后剩下的数为
-
,
-
...
-
,
再减去第i1项,则数列为 -
,
-
...
-
以此类推,最后剩下的数即为某两项之差
所以该题就转化为了求是否有 -
= k,即
= k +
升序排序后依次将+k插入set并查询
是否存在于set中即可
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#ifdef LOCAL
template<class t,class u>ostream& operator<<(ostream& os,const pair<t,u>& p){return os<<"("<<p.first<<","<<p.second<<")";}
template<class t>ostream& operator<<(ostream& os,const vector<t>& v){os<<"{"; for(auto e:v)os<<e<<","; return os<<"}";}
#endif
int n, m, t, k, a, b, c, d, cnt, mark, an, oT_To, x, y, z, ans;
int num[200005];
ll sum;
void solve() {
sum = 0;
cin >> n >> k;
set<int> st;
mark = 0;
for (int i = 0; i < n; ++i) {
cin >> num[i];
}
sort(num, num+n);
for (int i = 0; i < n; ++i) {
if (st.count(num[i])) {
mark = 1;
break;
}
st.insert(num[i]+k);
}
if (mark) {
cout << "YES\n";
} else cout << "NO\n";
}
int main () {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
oT_To = 1;
cin >> oT_To;
while (oT_To--) {
solve();
}
}
C
题意:
给出n个数,每次操作都可以使所有数都等于mod x(x 2), 问任意次操作后是否能使所有数相等
思路:
首先易知每次mod最大值即可让所有大于等于2的数变为0,
或每次mod最大值-1即可让所有大于等于3的数变为1,
但后者若有两个数相邻(a+1=b)则无法这样操作,
会使两数中较小的数变为0,较大的数变为1,从而不可能符合题意。
故如果给出的n个数中有1并且有相邻的数时无解,
否则若不含1则重复mod最大
值,反之mod最大值-1即可
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#ifdef LOCAL
template<class t,class u>ostream& operator<<(ostream& os,const pair<t,u>& p){return os<<"("<<p.first<<","<<p.second<<")";}
template<class t>ostream& operator<<(ostream& os,const vector<t>& v){os<<"{"; for(auto e:v)os<<e<<","; return os<<"}";}
#endif
int n, m, t, k, a, b, c, d, cnt, mark, an, oT_To, x, y, z, ans;
void solve() {
cin >> n;
mark = 0;
set<int>st;
for (int i = 0; i < n; ++i) {
cin >> a;
st.insert(a);
}
for (int i : st) {
if (st.count(i+1)) {
mark = 1;
break;
}
}
if (mark && st.count(1)) cout << "NO\n";
else cout << "YES\n";
}
int main () {
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
oT_To = 1;
cin >> oT_To;
while (oT_To--) {
solve();
}
}
D
题意:
对于一个数n,如果它能被表示成k个mod k不同的数之和,那么它就是一个“k好”数,给出一个数,问它是否是k好数,如果是则输出任意一个k
思路:
首先分析k好数定义可知,k好数可以表示为 (
) , 即
当k为偶数时,该式为;当k为奇数时,该式为
观察以上两个式子可知,k好数总能化为一个形如的式子
所以我们只需要将n转换为一个奇数和偶数的积即可
具体做法连续除2即可,我们经过这个操作就可以得到一对b, c满足且bc一为奇数一为偶数
(注意2的若干次方必定不是k好数,因为k > 1)
将偶数*2后的较小数作为k带入方程则可解出答案,k即为min(奇数,偶数*2)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#ifdef LOCAL
template<class t,class u>ostream& operator<<(ostream& os,const pair<t,u>& p){return os<<"("<<p.first<<","<<p.second<<")";}
template<class t>ostream& operator<<(ostream& os,const vector<t>& v){os<<"{"; for(auto e:v)os<<e<<","; return os<<"}";}
#endif
ll n, m, t, k, a, b, c, d, cnt, mark, an, oT_To, x, y, z, ans;
void solve() {
cin >> n;
a = 2;
while ((n & 1) == 0) {
n >>= 1, a <<= 1;
}
if (n == 1) {
cout << "-1\n";
return;
}
cout << min(a, n) << '\n';
}
int main () {
oT_To = 1;
cin >> oT_To;
while (oT_To--) {
solve();
}
}
E
题意:
给出一颗树,要求给每个点赋权值使得删除树上任意一个点后剩下的每个连通块上的点权之和都相同
思路:
考虑使整颗数的点权之和为0,任意确定一个根节点(高度为0)后,
以高度为奇数的节点作为根节点的子树的点权和为1,
以高度为偶数的节点作为根节点的子树的点权和为-1,
将每个点的权值设为1或-1(根节点为0)然后减去子节点个数*-1或1即可实现。
这样构造出来的树任意删去一个节点后剩下的每个连通块都是1(-1,由删去节点的高度决定)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#ifdef LOCAL
template<class t,class u>ostream& operator<<(ostream& os,const pair<t,u>& p){return os<<"("<<p.first<<","<<p.second<<")";}
template<class t>ostream& operator<<(ostream& os,const vector<t>& v){os<<"{"; for(auto e:v)os<<e<<","; return os<<"}";}
#endif
int n, m, t, k, a, b, c, d, cnt, mark, an, oT_To, x, y, z, ans;
vector <vector <int> > ve;
vector <int> val;
void dfs(int now, int fa, int d) {
val[now] = d;
val[fa] -= d;
for (int i : ve[now]) {
if (i != fa) {
dfs(i, now, d == 0 ? 1 : -d);
}
}
}
void solve() {
cin >> n;
ve = vector <vector <int>> (n+1);
val = vector <int> (n+1);
for (int i = 1; i < n; ++i) {
cin >> a >> b;
ve[a].push_back(b);
ve[b].push_back(a);
}
dfs(1, 0, 0);
for (int i = 1; i <= n; i++) {
cout << val[i] << (i == n ? '\n' : ' ');
}
}
int main () {
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
oT_To = 1;
cin >> oT_To;
while (oT_To--) {
solve();
}
}