Codeforces Round #811 (Div. 3) E Add Modulo 10

原题链接:Problem - E - Codeforces

题目描述:

You are given an array of nn integers a1,a2,…,ana1,a2,…,an

You can apply the following operation an arbitrary number of times:

  • select an index ii (1≤i≤n1≤i≤n) and replace the value of the element aiai with the value ai+(aimod10)ai+(aimod10), where aimod10aimod10 is the remainder of the integer dividing aiai by 1010.

For a single index (value ii), this operation can be applied multiple times. If the operation is applied repeatedly to the same index, then the current value of aiai is taken into account each time. For example, if ai=47ai=47 then after the first operation we get ai=47+7=54ai=47+7=54, and after the second operation we get ai=54+4=58ai=54+4=58.

Check if it is possible to make all array elements equal by applying multiple (possibly zero) operations.

For example, you have an array [6,11][6,11].

  • Let's apply this operation to the first element of the array. Let's replace a1=6a1=6 with a1+(a1mod10)=6+(6mod10)=6+6=12a1+(a1mod10)=6+(6mod10)=6+6=12. We get the array [12,11][12,11].
  • Then apply this operation to the second element of the array. Let's replace a2=11a2=11 with a2+(a2mod10)=11+(11mod10)=11+1=12a2+(a2mod10)=11+(11mod10)=11+1=12. We get the array [12,12][12,12].

Thus, by applying 22 operations, you can make all elements of an array equal.

Input

The first line contains one integer tt (1≤t≤1041≤t≤104) — the number of test cases. What follows is a description of each test case.

The first line of each test case contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the size of the array.

The second line of each test case contains nn integers aiai (0≤ai≤1090≤ai≤109) — array elements.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case print:

  • YES if it is possible to make all array elements equal;
  • NO otherwise.

You can print YES and NO in any case (for example, the strings yEs, yes, Yes and YES will be recognized as a positive answer) .

Example

input

Copy

10
2
6 11
3
2 18 22
5
5 10 5 10 5
4
1 2 4 8
2
4 5
3
93 96 102
2
40 6
2
50 30
2
22 44
2
1 5

output

Copy

Yes
No
Yes
Yes
No
Yes
No
No
Yes
No

Note

The first test case is clarified above.

In the second test case, it is impossible to make all array elements equal.

In the third test case, you need to apply this operation once to all elements equal to 55.

In the fourth test case, you need to apply this operation to all elements until they become equal to 88.

In the fifth test case, it is impossible to make all array elements equal.

In the sixth test case, you need to apply this operation to all elements until they become equal to 102102.

思路:

不妨先打个表看看不断地进行ai+(ai%10)操作的输出结果:

测试代码:

 控制台输出结果:

 不难发现规律,数可以分为三类:

第一类是以 0 或 5 结尾的数。

第二类是以2、4、6、8结尾的数。

第三类是以1、3、7、9结尾的数,此类数进行一次ai+(ai%10)操作后就转换成了第二类,所以为了便于讨论,我们将其视作第二类

因为这两类数内部可以相互转化,但是不能跨类别转化,所以当同时存在这两类数就判负

考虑以0或5结尾的数,显然只有5结尾的数字进行ai+(ai%10)操作是有意义的,以0结尾的数字进行这个操作会保持不变。所以如果一个数组只有这一类数字,我们可以将所有数字都进行一次ai+(ai%10)操作,最后检查所有数字是否相等即可。

考虑另一类数:我们发现他们的结尾数字是有规律的 2−4−8−6-2。

所以这也就启发我们:他们最后变成的相等的数一定是整个数组的最大值,并且时最大值将最后一位变成 2−4−8−6 中的某一个。

那么就每个数判一下能不能变成最大值Max就好了。如果只是一味的每个数字一步步进行ai+(ai%10)运算,那么操作步数太多,会超时,我们观察会发现2->4->8->6->2,这样一个轮回是20,所以我们可以对每个数字都先加20,加到不超过Max的最大值。然后再进行ai+(ai%10)运算,看能否达到Max。

代码(CPP):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + 10;
int n, a[maxn];

int main()
{
    freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        cin >> n;
        int Max = 0;
        bool flag_1 = false, flag_5 = false;  // 两类数字
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            int m = a[i] % 10;
            if(m == 0 || m == 5)  // 存在第一类数
                flag_5 = true;  
            else  // 存在第二类数
            {
                flag_1 = true;
                if(m != 2 && m != 4 && m != 6 && m != 8)  // 将结尾是1、3、7、9的数字进行一次ai+(ai%10)运算,转换为结尾为2、4、6、8的数
                    a[i] += a[i] % 10;
            }
            Max = max(Max, a[i]);  // 记录数组最大值
        }
        if(flag_1 && flag_5)  // 两类数同时存在则直接判负
        {
            cout << "NO\n";
            continue;
        }
        else if(flag_5)
        {   // 第一类数:显然只有以 5 结尾的数的改变有意义,而且只可以改变一次,所以就对这些数全部更改一次。
            for (int i = 1; i <= n; i++)
            {
                a[i] += a[i] % 10;
            }
            // 然后判断整个序列是否相等就好了
            bool flag = true;
            for (int i = 2; i <= n; i++)
            {
                if(a[i] != a[i - 1])
                {
                    flag = false;
                    break;
                }
            }
            cout << (flag ? "YES\n" : "NO\n");
        }
        else
        {   // 第二类数
            bool ans = true;
            for (int i = 1; i <= n; i++)
            {
                a[i] = a[i] + (Max - a[i]) / 20 * 20; // 一个轮回是20,所以我们可以对每个数字都先加20,加到不超过Max的最大值
                while(a[i] < Max)  // 然后再进行ai+(ai%10)运算,看能否达到Max
                {
                    a[i] += a[i] % 10;
                }
                if(a[i] > Max)
                {
                    ans = false;
                    break;
                }
            }
            cout << (ans ? "YES\n" : "NO\n");
        }
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值