洛谷 CF1575D Divisible by Twenty-Five 题解

本蒟蒻的第一篇题解,请大家笑纳。
感谢管理员大大指出了笔误。

题目传送门

一、题目分析

思路

我们都知道,\(0\) 是任何数的倍数,所以 \(0\) 要特判。当输入 \(0\)\(\_\)\(X\) 的情况,应该先输出 \(1\),并且 return 0

因为判断是否为 \(25\) 的倍数,只需要判断最后两位,当最后两位为 \(25\)\(50\)\(75\)\(00\) 时,这个数就为 \(25\) 的倍数。
注意:本题规定所有数字都不能含有前导 \(0\)(\(0\) 本身除外)。所以当 \(\text{字符串长度}\le2\) 时,你需要注意不能有 \(00\) 这种情况。

\(\_\) 的可能性

因为要考虑前导 \(0\) 的情况,所以我们可以把字符串分为两种。

\(\text{字符串长度}\ge3\)

\(\text{字符串长度}\ge3\) 时,每一个 \(\_\) 都可以表示 \(0-9\),但是一下情况需要注意。

  • 如果 \(\_\) 在最高位,那么它的取值只能为 \(1-9\)
  • 如果字符串是以 \(\_5\) 结尾,则 \(\_\) 只能为 \(2\)\(7\)
  • 如果字符串是以 \(\_0\) 结尾,则 \(\_\) 只能为 \(0\)\(5\)
  • 如果字符串是以 \(5\_\)\(0\_\) 结尾,则 \(\_\)只能为 \(0\)
  • 如果字符串是以 \(2\_\)\(7\_\) 结尾,则 \(\_\)只能为 \(5\)
  • 如果字符串是以 \(\_\_\)结尾,则末尾两位只能为 \(00\)\(25\)\(50\)\(75\)
  • 其余情况都为无解。

\(\text{字符串长度}\le2\)

\(\text{字符串长度}\le2\) 时,有一下几种情况。

  • 如果字符串是 \(\_5\),则 \(\_\) 只能为 \(2\)\(7\)
  • 如果字符串是 \(\_0\),则 \(\_\) 只能为 \(5\)
  • 如果字符串是 \(5\_\),则 \(\_\)只能为 \(0\)
  • 如果字符串是 \(2\_\)\(7\_\),则 \(\_\)只能为 \(5\)
  • 如果字符串是 \(\_\_\) 结尾,则末尾两位只能为 \(25\)\(50\)\(75\)
  • 其余情况都为无解。

X 的可能性

因为每一个 \(X\) 都表示同一个数字,所以这时你就要考虑最高位的问题。

\(\text{字符串长度}\ge3\)

\(\text{字符串长度}\ge3\) 时,\(X\) 可以表示 \(0-9\),但是一下情况需要注意。

  • 如果 \(X\) 在最高位,那么它的取值只能为 \(1-9\)
  • 如果字符串是以 \(X5\) 结尾,则 \(X\) 只能为 \(2\)\(7\)
  • 如果字符串是以 \(X0\) 结尾,则 \(X\) 只能为 \(0\)\(5\),如果 \(X\)\(0\),还要考虑最高位。
  • 如果字符串是以 \(5X\)\(0X\) 结尾,则 \(X\)只能为 \(0\),并且还要考虑最高位。
  • 如果字符串是以 \(2X\)\(7X\) 结尾,则 \(X\)只能为 \(5\)
  • 如果字符串是以 \(XX\)结尾,则 \(X\)只能为 \(0\),并且也要考虑最高位。
  • 其余情况都为无解。

\(\text{字符串长度}\le2\)

\(\text{字符串长度}\le2\) 时。

  • 如果字符串是 \(X5\),则 \(X\) 只能为 \(2\)\(7\)
  • 如果字符串是 \(X0\),则 \(X\) 只能为 \(5\)
  • 如果字符串是 \(5X\),则 \(X\)只能为 \(0\)
  • 如果字符串是 \(2X\)\(7X\),则 \(X\)只能为 \(5\)
  • 如果字符串是 \(XX\),则无解,因为不能出现 \(00\)
  • 如果字符串是 \(X\_\)\(\_X\) 结尾,则只有 \(25\)\(50\)\(75\) 的情况。
  • 其余情况都为无解。

二、统计个数

很显然,本题需要统计 \(X\)\(\_\) 的数量。
而最高位和最后两位都需要另外统计。

统计字符个数的代码:

char a[10000]={};
cin>>a;
int x=0,y=0;  //x表示字符X的数量,y表示字符_的数量
for(int i=1;i<strlen(a)-2;i++)  //strlen()函数是求字符串的长度
{
	if(a[i]=='X')x++;
	if(a[i]=='_')y++;
}

三、计算数量

而最高位是否为 \(X\)\(\_\),需要特殊处理。

int w=0,z=0;//w表示最高位是否为X,z表示最高位是否为_。
if(a[0]=='X')w=1;
if(a[0]=='_')z=1;

当最后两位能够成的数量求出来时,结果也就算出来了,可以推出以下代码。

1/*前面这个数字表示后两位构成的种数*/*(w==1?9:x==0?1:1)/*a?b:c 是三目运算符,若a为真则返回b,否则返回c,前面的三目运算符表示对第一个字符为X的情况特判*/*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y)));//后面的自行理解

四、AC代码

以下是我的完整代码:

#include<bits/stdc++.h> //你熟悉的万能头
using namespace std;
char a[10]={};
int main()
{
	cin>>a;
	if(strlen(a)<=2)  //当a的长度≤2时的情况
	{
		if(strlen(a)==1)
		{
			if(a[0]=='0'||a[0]=='X'||a[0]=='_')cout<<1;  ///特判
			else cout<<0;
			return 0;
		}
		else
		{
			if((a[0]=='2'||a[0]=='7')&&a[1]=='5')cout<<1;
			else if(a[0]=='5'&&a[1]=='0')cout<<1;
			else if(a[0]=='X'&&a[1]=='5')cout<<2;
			else if(a[0]=='_'&&a[1]=='5')cout<<2;
			else if(a[0]=='X'&&a[1]=='0')cout<<1;
			else if(a[0]=='_'&&a[1]=='0')cout<<1;
			else if(a[0]=='X'&&a[1]=='X')cout<<0;
			else if(a[0]=='X'&&a[1]=='_')cout<<3;
			else if(a[0]=='_'&&a[1]=='X')cout<<3;
			else if(a[0]=='_'&&a[1]=='_')cout<<3;
			else if(a[0]=='2'&&a[1]=='X')cout<<1;
			else if(a[0]=='5'&&a[1]=='X')cout<<1;
			else if(a[0]=='7'&&a[1]=='X')cout<<1;
			else if(a[0]=='2'&&a[1]=='_')cout<<1;
			else if(a[0]=='5'&&a[1]=='_')cout<<1;
			else if(a[0]=='7'&&a[1]=='_')cout<<1;
                          				//所有情况
			else cout<<0;
		}
		return 0;
	}
	int x=0,y=0,w=0,z=0;//X个数、_个数、第一位是否为X、第一位是否为_
	for(int i=1;i<strlen(a)-2;i++)
	{
		if(a[i]=='X')x++;
		if(a[i]=='_')y++;
        		//统计X和_的个数
	}
	if(a[0]=='0')//以0开头的情况
	{
		cout<<0;
		return 0;
	}
	if(a[0]=='X')w=1;
	if(a[0]=='_')z=1;
	if(a[strlen(a)-1]=='5')
	{
		if(a[strlen(a)-2]=='2'||a[strlen(a)-2]=='7')cout<<(w==1?9:x==0?1:10)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y)));
		else if(a[strlen(a)-2]=='X')cout<<(long long int)(2*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else if(a[strlen(a)-2]=='_')cout<<(long long int)(2*(w==1?9:x==0?1:10)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else cout<<0;
	}
	else if(a[strlen(a)-1]=='0')
	{
		if(a[strlen(a)-2]=='5'||a[strlen(a)-2]=='0')cout<<(w==1?9:x==0?1:10)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y)));
		else if(a[strlen(a)-2]=='X')cout<<(long long int)(((w==1)?1:2)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else if(a[strlen(a)-2]=='_')cout<<(long long int)(2*(w==1?9:x==0?1:10)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else cout<<0;
	}
	else if(a[strlen(a)-1]=='X')
	{
		if(a[strlen(a)-2]=='X')cout<<((w==1)?0:1)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y)));
		else if(a[strlen(a)-2]=='_')cout<<(long long int)(((w==1)?2:4)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else if(a[strlen(a)-2]=='2'||a[strlen(a)-2]=='7')cout<<(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y)));
		else if(a[strlen(a)-2]=='5'||a[strlen(a)-2]=='0')cout<<((w==1)?0:1)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y)));
		else cout<<0;
	}
	else if(a[strlen(a)-1]=='_')
	{
		if(a[strlen(a)-2]=='X')cout<<(long long int)(((w==1)?3:4)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else if(a[strlen(a)-2]=='_')cout<<(long long int)(4*(w==1?9:x==0?1:10)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else if(a[strlen(a)-2]=='2'||a[strlen(a)-2]=='5'||a[strlen(a)-2]=='7'||a[strlen(a)-2]=='0')cout<<(long long int)((w==1?9:x==0?1:10)*(z==1?9*((y==0)?1:(pow(10,y))):(y==0?1:pow(10,y))));
		else cout<<0;
	}
	else cout<<0;
    						//以上是所有情况
	return 0;
}

END

posted @ 2024-01-21 14:02  fxwqctb  阅读(6)  评论(0编辑  收藏  举报