背景:
被教练拉着讲题
怎么可能嘛(大雾)我发个题解给他们看就好了......
思路:可以按末尾分类,0和5是一坨,其他数字都会转化到2 4 8 6循环,然后可以随便搞搞...
详细一点:
0->0
1->2
2->4
3->6
4->8
5->0
6->2
7->4
8->6
9->8
末尾变到0就是死路一条了对吧!
其他情况变成2 4 6 8中的一个,再变下去,末尾会在这四个数中循环,那么对于一组输入,如果这些数末尾只有5和0肯定很好处理对吧,如果“5性”的数和“2性”的数都有就肯定no了,因为它们永不能相互转化
就是说这两类数水火不容,1永不能变0,5也永不能变6,现在只用考虑一种情况:只有绿色类(“2性”)的数,此时就要关注非个位的部分了,一个2486循环节会发生两次进位,我们先暴力把所有数的末尾化得一样,比如统一化成2,然后看这些数/10后奇偶性是否相同就好啦!
比如93 96 102这组样例
全把末位化成2后全是102,显然可
再看一组数据:93 96 122
化完长这样,去掉末位分别是 10 10 12,它们奇偶性一样,此时也yes,因为102可以通过一个2486循环节变成122
再看一组数据:93 96 112
去末位是 10 10 11,此时no,因为奇偶性不同了,,102永不能变成112,因为一个循环节得进两次位,同理,62可以变82,但不能变92,这就解释了“用去掉末位后数的奇偶性判定答案”的论断
直接上代码!!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
ll res=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') res=(res<<3)+(res<<1)+(c^48),c=getchar();
return res*f;
}
const int N=1000006;
int n,a[N];
inline void convert(int &x)
{
x+=x%10;
}
bool check()
{
int flag_5=false,flag_2=false;
for(int i=1;i<=n;i++)
{
if(a[i]%10==5||a[i]%10==0)
{
flag_5=true;
convert(a[i]);
}
else
{
flag_2=true;
while(a[i]%10!=2)
convert(a[i]);
a[i]=a[i]/10&1;
}
}
if(flag_5&&flag_2)
return false;
for(int i=2;i<=n;i++)
if(a[i]!=a[i-1])
return false;
return true;
}
int main(){
int t=read();
while(t--)
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
puts(check()?"Yes":"No");
}
return 0;
}
PS:两个flag就是说两种数分别有没有,convert函数就是模拟那个变化