CF1692F 3SUM 题解
题目
链接
https://www.luogu.com.cn/problem/CF1692F
字面描述
题面翻译
题目描述
给出一个长度为 n n n 的正整数数组 a a a,判断是否存在三个不同的下标 i i i, j j j, k k k,使 a i + a j + a k a_i+a_j+a_k ai+aj+ak以数字 3 3 3 结尾。
输入格式
第一行包含一个整数 t t t ( 1 ≤ t ≤ 1000 ) (1≤t≤1000) (1≤t≤1000)——测试数据的组数。
每组测试数据的第一行包含一个整数 $ n $ ( $ 3 \leq n \leq 2 \cdot 10^5 $ ) ——数组的长度。
每组测试数据的第二行包含 n n n 个整数 $ a_1, a_2, \dots, a_n $ ( $ 1 \leq a_i \leq 10^9 $ ) ——数组的元素。
所有测试数据中的 n n n 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105 。
输出格式
输出 t t t 行,每行包含对应的测试数据的答案。如果存在三个不同的下标 i i i, j j j, k k k,使 a i + a j + a k a_i+a_j+a_k ai+aj+ak以数字 3 3 3 结尾,则输出 “YES”,否则输出 “NO”。
你可以输出任意大小写的答案(例如,字符串 “yEs”、“yes”、"Yes "和 "YES "都将被认为是正确的答案)。
样例 #1
样例输入 #1
6
4
20 22 19 84
4
1 11 1 2022
4
1100 1100 1100 1111
5
12 34 56 78 90
4
1 9 8 4
6
16 38 94 25 18 99
样例输出 #1
YES
YES
NO
NO
YES
YES
提示
在第一组测试数据中,你可以选择 $ i=1 $ , $ j=4 $ , $ k=3 $,那么 $ a_1 + a_4 + a_3 = 20 + 84 + 19 = 123 $,以数字 3 3 3 结尾
在第二组测试数据中,你可以选择 $ i=1 $ , $ j=2 $ , $ k=3 $,那么 $ a_1 + a_2 + a_3 = 1 + 11 + 1 = 13 $,以数字 3 3 3 结尾
在第三组测试数据中,可以证明不存在这样的 i i i, j j j, k k k。请注意,$ i=4 $ , $ j=4 $ , $ k=4 $ 并不是一个有效的答案,因为尽管 $ a_4 + a_4 + a_4 = 1111 + 1111 + 1111 = 3333 $ 以数字3结尾,但题目中要求选择的三个下标是不同的。
在第四组测试数据中,可以证明不存在这样的 i i i, j j j, k k k。
在第五组测试数据中,你可以选择 $ i=4 $ , $ j=3 $ , $ k=1 $,那么 $ a_4 + a_3 + a_1 = 4 + 8 + 1 = 13 $,以数字 3 3 3 结尾
在第六组测试数据中,你可以选择 $ i=1 $ , $ j=2 $ , $ k=6 $,那么 $ a_1 + a_2 + a_6 = 16 + 38 + 99 = 153 $,以数字 3 3 3 结尾
题目描述
Given an array $ a $ of positive integers with length $ n $ , determine if there exist three distinct indices $ i $ , $ j $ , $ k $ such that $ a_i + a_j + a_k $ ends in the digit $ 3 $ .
输入格式
The first line contains an integer $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.
The first line of each test case contains an integer $ n $ ( $ 3 \leq n \leq 2 \cdot 10^5 $ ) — the length of the array.
The second line of each test case contains $ n $ integers $ a_1, a_2, \dots, a_n $ ( $ 1 \leq a_i \leq 10^9 $ ) — the elements of the array.
The sum of $ n $ across all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
Output $ t $ lines, each of which contains the answer to the corresponding test case. Output “YES” if there exist three distinct indices $ i $ , $ j $ , $ k $ satisfying the constraints in the statement, and “NO” otherwise.
You can output the answer in any case (for example, the strings “yEs”, “yes”, “Yes” and “YES” will be recognized as a positive answer).
样例 #1
样例输入 #1
6
4
20 22 19 84
4
1 11 1 2022
4
1100 1100 1100 1111
5
12 34 56 78 90
4
1 9 8 4
6
16 38 94 25 18 99
样例输出 #1
YES
YES
NO
NO
YES
YES
提示
In the first test case, you can select $ i=1 $ , $ j=4 $ , $ k=3 $ . Then $ a_1 + a_4 + a_3 = 20 + 84 + 19 = 123 $ , which ends in the digit $ 3 $ .
In the second test case, you can select $ i=1 $ , $ j=2 $ , $ k=3 $ . Then $ a_1 + a_2 + a_3 = 1 + 11 + 1 = 13 $ , which ends in the digit $ 3 $ .
In the third test case, it can be proven that no such $ i $ , $ j $ , $ k $ exist. Note that $ i=4 $ , $ j=4 $ , $ k=4 $ is not a valid solution, since although $ a_4 + a_4 + a_4 = 1111 + 1111 + 1111 = 3333 $ , which ends in the digit $ 3 $ , the indices need to be distinct.
In the fourth test case, it can be proven that no such $ i $ , $ j $ , $ k $ exist.
In the fifth test case, you can select $ i=4 $ , $ j=3 $ , $ k=1 $ . Then $ a_4 + a_3 + a_1 = 4 + 8 + 1 = 13 $ , which ends in the digit $ 3 $ .
In the sixth test case, you can select $ i=1 $ , $ j=2 $ , $ k=6 $ . Then $ a_1 + a_2 + a_6 = 16 + 38 + 99 = 153 $ , which ends in the digit $ 3 $ .
思路
本题 ∑ n ≤ 2 ⋅ 1 0 5 \sum n ≤ 2 \cdot 10^5 ∑n≤2⋅105数据看起来想让人**
但我们只需要考虑3个数末尾数之和 % 10 \%10 %10是否为3,且能否实现
总结一下,做法如下:
-
只需要一个长度为 10 10 10的桶记录所有数末尾为 [ 0 , 9 ] [0,9] [0,9]的次数
-
在循环暴力这三个数之和即可
最坏时间复杂度: O ( t ⋅ 1 e 3 ) ≈ 1 e 7 \Omicron(t \cdot 1e3)≈ 1e7 O(t⋅1e3)≈1e7
代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=100+10;
int t,n;
int cnt[maxn];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=0;i<10;i++)cnt[i]=0;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
cnt[x%10]++;
}
/*
for(int i=0;i<=9;i++)printf("%d ",cnt[i]);
printf("\n");
*/
bool flag=false;
for(int i=0;i<=9;i++){
for(int j=0;j<=9;j++){
for(int k=0;k<=9;k++){
if((i+j+k)%10!=3)continue;
cnt[i]--;
cnt[j]--;
cnt[k]--;
if(cnt[i]>=0&&cnt[j]>=0&&cnt[k]>=0){
flag=true;
break;
}
cnt[i]++;
cnt[j]++;
cnt[k]++;
}
if(flag)break;
}
if(flag)break;
}
if(flag)printf("YES\n");
else printf("NO\n");
}
return 0;
}