A - Good Pairs
题意
找一个数对满足题目所给的公式
输出下标
题解
输出最大值和最小值的下标就行了,因为本质上就是这个点到两端的距离之和
Code
int T;
int n;
PII a[N];
void solve(){
cin >> n;
for (int i = 1; i <= n; i++){
cin >> a[i].x;
a[i].y = i;
}
sort(a + 1, a + 1 + n);
cout << a[1].y << ' ' << a[n].y << endl;
}
B - Subtract Operation
题意
每次选择一个数对全体数组的数来相减,问最后剩一个数能不能时k
题解
本质上,每次操作过后两个数的相对大小关系是不会改变的。
所以说,最后剩的两个数是多少,与他们最初的差是一样的
所以对于每一个数检查一下有没有与之对应的数使得两者相加为k
Code
int T;
ll n, k;
int a[N];
void solve(){
cin >> n >> k;
// ll summ = 0;
map<ll, int> m;
int maxx = 0;
for (int i = 1; i <= n; i++){
cin >> a[i];
maxx = max(a[i], maxx);
m[a[i]]++;
}
for (ll i = 1; i <= n; i++){
if(m[a[i] + k]){
cout << "YES" << endl;
re;
}
}
cout << "NO" << endl;
}
C - Make Equal With Mod
题意
给定数组,可以选取一个数 2 ≤ k 2\leq k 2≤k使得,将数组中的所有元素变为 a i % k a_i \%k ai%k
若干操作后,使得数组各元素相等
题解
因为操作可以无限次,那么我们最开始的想法不妨设最后都变成0
那不就都除以这个数本身就完了吗
但是题目要求 2 ≤ k 2\leq k 2≤k,如果数组中出现了1的话,那么肯定是不能除以自己的,而要满足题意,那必须得是让所有的数变成1,也就是 mod 上他自己减一,就可以让他们全部都变成1了
但是如果数组中出现了两个数相差为1的情况,这时候按照上面的方法就会出现0了,之后就不会再相等了
而当数组出现了0,那么还是遵循上面第一条的情况就可以了
如果数组中出现了0和1,就符合第二种说的情况
Code
int T;
int n;
int a[N];
void solve(){
int one = 0;
int ok = 1;
cin >> n;
for (int i = 1; i <= n; i++){
cin >> a[i];
if(a[i] == 1)
one = 1;
if(i > 1 && a[i - 1] != a[i])
ok = 0;
}
if(ok){
cout << "YES" << endl;
re;
}
if(one){
sort(a + 1, a + 1 + n);
for (int i = 2; i <= n; i++){
if(a[i] - a[i - 1] == 1){
cout << "NO" << endl;
re;
}
}
cout << "YES" << endl;
re;
}
else cout << "YES" << Endl;
}
D - K-good
题意
给你一个数n,问能不能拆成k个数的和使这k个数模k的结果都相同
输出这个k
题解
假设我们现在n已经被拆成了k个数,即
a
1
+
a
2
+
a
3
+
⋯
+
a
k
=
n
a_1+a_2+a_3+\cdots+a_k=n
a1+a2+a3+⋯+ak=n
而这些数%k都不相同,而且有k个,那么显然这些数一定都是
0
∼
k
−
1
0 \sim k-1
0∼k−1之间的,那么
n
=
k
∗
(
k
−
1
)
2
+
t
k
n
=
k
2
−
k
+
2
t
k
2
n
=
k
2
∗
(
k
−
1
+
2
t
)
n
=
k
∗
(
k
−
1
+
2
t
)
2
n=\frac{k*(k-1)}{2}+tk \\ n=\frac{k^2-k+2tk}{2} \\ n=\frac{k}{2}*(k-1+2t) \\ n=k*\frac{(k-1+2t)}{2}
n=2k∗(k−1)+tkn=2k2−k+2tkn=2k∗(k−1+2t)n=k∗2(k−1+2t)
若k为奇数,则
k
−
1
+
2
t
k-1+2t
k−1+2t为偶数;若k为偶数,则
k
−
1
+
2
t
k-1+2t
k−1+2t为奇数
即无论怎样,2n必定为一寄一偶相乘得到的
那么我们可以把这个偶数求出来,当2n不能再被2整除的时候,奇数也就出来了
需要注意的是n构造的式子中,已经减了一个2的质因子
最后输出的最小值是因为等式成立的话,k+2t-1一定是大于k的,所以输出最小
Code
ll n;
void solve(){
cin >> n;
ll tmp = n;
int cnt = 1;
while(tmp % 2 == 0)
tmp /= 2, cnt++;
if(tmp == 1) // 不满足一寄一偶
cout << -1 << endl;
else{
cout << min(tmp, 1ll << (cnt)) << endl;
}
cout << endl;
}
E - Equal Tree Sums
参考https://www.zhihu.com/people/pzr-84
void dfs(int u, int fa){
if(fa != -1)
col[u] = !col[fa];
else
col[u] = 1;
for(auto v: g[u]){
if(v != fa && !col[v]){
dfs(v, u);
}
}
}
void solve(){
cin >> n;
for (int i = 1; i <= n; i++){
d[i] = col[i] = 0;
g[i].clear();
}
for (int i = 1; i < n; i++){
int a, b;
cin >> a >> b;
d[a]++;
d[b]++;
g[a].pb(b);
g[b].pb(a);
}
dfs(1, -1);
for (int i = 1; i <= n; i++){
if(col[i])
cout << -d[i] << ' ';
else
cout << d[i] << ' ';
}
cout << endl;
}