赞
踩
有 n n n 个球,第 i i i 个球上的序号是 a i a_i ai ,保证对任意 a i a_i ai 都有 a i ≤ a i + 1 a_i \leq a_{i+1} ai≤ai+1 。现在你要给球涂上颜色,保证在球按照颜色分开后,每种颜色的球序号从小到大是严格递增的,也就是只考虑某种颜色的球的情况下,对相邻的 a i a_i ai、 a j a_j aj,均有 a i < a i + 1 a_i \lt a_{i+1} ai<ai+1 。问最少需要几种颜色,能达到这个要求?
问题可以化为:原数组中有可能有多个重复相同的数字,分开后的数组中不能有重复相同的数字。因此,只需要找到原数组所有元素中出现次数最多的即可。
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef pair<int, int> P; typedef long long ll; const int N = 1e6 + 9; const ll mod = 1e9 + 7; int main() { int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); int nowcnt = 0; int maxc = 0; int nowx = 0; for(int i = 0; i < n; i++) { int x; scanf("%d", &x); if(x != nowx) { maxc = max(maxc, nowcnt); nowx = x; nowcnt = 1; } else { nowcnt++; } } cout << max(maxc, nowcnt) << endl; } return 0; }
在1~9中,李华最喜欢的数字是 d d d 。如果一个正整数在其十进制表示下含有 d d d ,则李华称之为幸运数字。现给定一些数字,问你他们能否被分解为几个(一个或多个)幸运数字相加?
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef pair<int, int> P; typedef long long ll; const int N = 1e6 + 9; const ll mod = 1e9 + 7; int main() { int T; scanf("%d", &T); while(T--) { int q, d; scanf("%d%d", &q, &d); for(int i = 0; i < q; i++) { bool flag = 0; ll x; scanf("%lld", &x); if(x >= 10 * d) { printf("YES\n"); continue; } int tmp = x % 10; for(int i = 1; i < 10; i++) { if(i * d > x) break; if(i * d % 10 == tmp) { flag = 1; break; } } if(flag) printf("YES\n"); else printf("NO\n"); } } return 0; }
数组 a a a 中有 2 n 2n 2n 个整数,且数组中的元素满足,若 a i a_i ai 在数组中,则必有且仅有一个 a j = a i a_j = a_i aj=ai,即每个数的相反数都在其中。现给定一个数组 d d d ,其中 d i = ∑ j = 1 n ∣ a i − a j ∣ d_i = \sum_{j = 1}^n |a_i - aj| di=∑j=1n∣ai−aj∣,问能不能推出一个满足要求的数组 a a a ?无需输出 a a a 的内容,只需要判断。
参考:
Codeforces Round #698 (Div. 2)-C. Nezzar and Symmetric Array-题解
Codeforces Round #698 (Div. 2)_
我们可以思考: d d d 和 a a a 有哪些相关的特性?
综上,我们可以把特性概括/衍生为以下几点:
第一点和第二点通过map来实现,因为数据范围1e9,数组存不下;
第三点,我们分类讨论一下,对于任意的 ∣ a i − a j ∣ + ∣ a i − ( − a j ) ∣ |a_i - a_j| + |a_i - (-a_j)| ∣ai−aj∣+∣ai−(−aj)∣ ,如果 a i > a j a_i \gt a_j ai>aj,则 ∣ a i − a j ∣ + ∣ a i − ( − a j ) ∣ = 2 a i |a_i - a_j| + |a_i - (-a_j)| = 2a_i ∣ai−aj∣+∣ai−(−aj)∣=2ai;若 a i < a j a_i \lt a_j ai<aj,则 ∣ a i − a j ∣ + ∣ a i − ( − a j ) ∣ = 2 a j |a_i - a_j| + |a_i - (-a_j)| = 2a_j ∣ai−aj∣+∣ai−(−aj)∣=2aj。所以其实 d i d_i di就是 2 × ∑ j = 0 n m a x ( a i , a j ) 2 \times \sum_{j = 0}^n max(a_i, a_j) 2×∑j=0nmax(ai,aj),即 a i a_i ai 和其他所有正整数比较后最大的那个正整数的两倍,所以在已知 d i d_i di的情况下, a i = ( d i / 2 − s u m / n ) a_i = (d_i/2- sum/n) ai=(di/2−sum/n),其中 s u m = ∑ a j , a j > a i sum = \sum a_j, a_j \gt a_i sum=∑aj,aj>ai 。所以从大到小不重复的遍历所有 d i d_i di,将当前元素减去之前已经算出的元素(因为是从最大开始算,所以 s u m sum sum 的值其实就是之前元素的累加),再除以还剩下几个元素,判断是否能整除(且大于0)即可。
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef pair<int, int> P; typedef long long ll; const int N = 1e6 + 9; const ll mod = 1e9 + 7; map<ll, int> mp; priority_queue<ll> que; int main() { int T; scanf("%d", &T); while(T--) { mp.clear(); while(!que.empty()) que.pop(); int n; scanf("%d", &n); for(int i = 0; i < 2 * n; i++) { ll x; scanf("%lld", &x); mp[x]++; } bool flag = true; for (auto i : mp) { que.push(i.first); if (i.second != 2) { flag = false; break; } } if (!flag || que.size() != n) { cout << "NO" << endl; continue; } ll sum = 0; for(int i = n; i >= 1; i--) { ll x = que.top(); que.pop(); if(x - sum <= 0 || ((x - sum) % (2 * i)) != 0) { flag = false; break; } else { sum += (x - sum) / i; } } if (flag) { cout << "YES" << endl; } else { cout << "NO" << endl; } } }
黑板上有 n n n 个不同的整数,可以进行的操作是选取两个数 x , y x,y x,y,将 2 x − y 2x-y 2x−y 放回黑板(不删除选取的数)。问能否经过一系列的操作得出给定的 k k k。
参考:Codeforces Round #698 (Div. 2) D. Nezzar and Board,Codeforces Round #698 (Div. 2) A~F
裴蜀定理:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Np3gOfTy-1612356393165)(C:\Users\29039\AppData\Roaming\Typora\typora-user-images\image-20210201161808476.png)]
把操作看成
x
+
(
x
−
y
)
x + (x - y)
x+(x−y),则整个过程化为元素
x
x
x 加上两个数的差值。又,形如
a
3
−
a
1
a_3 - a_1
a3−a1 的差可以转换为
a
3
−
a
2
+
a
2
−
a
1
a_3 - a_2 + a_2 - a_1
a3−a2+a2−a1,所以任何差
a
n
−
a
m
a_n - a_m
an−am 都能化为
∑
i
=
1
n
−
1
(
a
i
+
1
−
a
i
−
∑
i
=
1
m
−
1
(
a
i
+
1
−
a
i
)
\sum_{i = 1}^{n - 1}(a_{i + 1} - a_i - \sum_{i = 1}^{m - 1}(a_{i + 1} - a_i)
∑i=1n−1(ai+1−ai−∑i=1m−1(ai+1−ai) 的形式,所以我们可以将
2
x
−
y
=
k
2x - y = k
2x−y=k 转化为:
a
1
+
k
1
∗
(
a
2
−
a
1
)
+
k
2
∗
(
a
3
−
a
2
)
+
…
+
k
n
−
1
∗
(
a
n
−
a
n
−
1
)
=
k
a_1 + k_1* (a_2 - a_1) + k_2* (a_3 - a_2) + …+ k_{n - 1}* (a_n - a_{n - 1}) = k
a1+k1∗(a2−a1)+k2∗(a3−a2)+…+kn−1∗(an−an−1)=k
k 1 ∗ ( a 2 − a 1 ) + k 2 ∗ ( a 3 − a 2 ) + … + k n − 1 ∗ ( a n − a n − 1 ) = k − a 1 k_1* (a_2 - a_1) + k_2* (a_3 - a_2) + …+ k_{n - 1}* (a_n - a_{n - 1}) = k - a_1 k1∗(a2−a1)+k2∗(a3−a2)+…+kn−1∗(an−an−1)=k−a1
的形式。
因此,只要存在 a i a_i ai,有其他所有数字的最大公约数等于 k − a i k - a_i k−ai,原式就成立。
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef pair<int, int> P; typedef long long ll; const int N = 3e5 + 19; const ll mod = 1e9 + 7; ll a[N]; int main() { int T; cin >> T; while(T--) { int n; ll k; cin >> n >> k; ll gcd = 0; for(int i = 0; i < n; i++) { cin >> a[i]; if(i < 1) continue; if(i == 1) { gcd = a[i] - a[i - 1]; continue; } gcd = __gcd(gcd, a[i] - a[i - 1]); } bool flag = 0; for(int i = 0; i < n; i++) { if((k - a[i]) % gcd == 0) { flag = 1; break; } } if(flag) cout << "YES\n"; else cout << "NO\n"; } return 0; }
给定 n n n 个点,对其进行重新排列,使之任意连续的三个点形成的角(以中间的点为顶点)小于 90 90 90 度。
参考:Codeforces Round #698 (Div. 2) - Zeronera - 博客园
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef pair<int, int> P; typedef long long ll; const int N = 1e4 + 19; const ll mod = 1e9 + 7; struct node { double x; double y; node(){} node(double a, double b){x = a; y = b;} }a[N]; bool vis[N]; double dis(node a, node b) { return sqrt( (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) ); } int main() { int n; queue<int> ans; scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%lf%lf", &a[i].x, &a[i].y); } int cnt = 0; int id = 0; vis[0] = 1; do { double maxdis = 0; int num = 0; ans.push(id + 1); for(int j = 0; j < n; j++) { if(vis[j]) continue; double tmp = dis(a[id], a[j]); if(tmp > maxdis) { maxdis = tmp; num = j; } } id = num; vis[id] = 1; cnt++; } while(cnt < n); while(!ans.empty()) { printf("%d", ans.front()); ans.pop(); if(!ans.empty()) printf(" "); } printf("\n"); return 0; }
多多包涵,共同进步
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。