关于模拟赛一题详解

本文探讨了一种特殊的数字转换规则,末尾为0或5的数无法互相转化,而其他数字遵循2486循环。关键在于判断不含0和5的数中,奇偶性是否一致,以此来决定是否能通过循环达到同一状态。博主提供了代码示例来说明这一原理的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

 被教练拉着讲题

 

怎么可能嘛(大雾)我发个题解给他们看就好了......

 

 

 思路:可以按末尾分类,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函数就是模拟那个变化
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值