杰哥特别喜欢和数字打交道,现在他有一个正整数X,他想知道有多少个满足要求的正整数D存在,要求是D是X的因子,并且D和X至少有一位相同。
★输入格式
只有一行,一个正整数X。(N<=1000000000)。
对于30%的数据,n<=100
对于50%的数据,n<=200
对于100%的数据,n<=1000000000
★输出格式
只有一行,一个整数表示满足要求的数字D的个数。
★输入样例
10
★输出样例
2
思路非常简单明了:首先我们必须找到X的所有因子,然后再对因子进行逐个操作。
//Matsuri
#include<cstdio>
#include<cmath>
#include<cstring>
#define MAX 12
int X,n=0;
int a[MAX],b[MAX]; //原数X拆完后存储于a,找到的因子拆完后存储于b
int split(int num,int l[]);
int isSameFigure(int XX,int ii) //判断X和它的因子是否存在相同的数字
{
int w1,w2; // 用来存位数
int flag=0; // 标记,找到相同数字的话就是1,并且以它作为输出值
memset(b,0,sizeof(b)); //把上一次调用该函数时遗留的b数组中的数据全部初始化
w1=split(XX,a);
w2=split(ii,b);
for (int i=1;i<=w1;i++)
{
for (int j=1;j<=w2;j++)
{
if (a[i]==b[j])
{
flag=1;
break;
}
}
if (flag==1) break;
}
return flag;
}
int split(int num,int l[]) // 拆数字用(*可以积累),小细节是拆完后每位数字是以倒序存储在数组里的
{
int numx,i=0;
numx=num;
while(numx)
{
l[++i]=numx%10;
numx=numx/10;
}
return i; // 返回的是待拆数字的位数(也就是a或b数组里面非0元素的个数)
}
int main()
{
scanf("%d",&X);
//下面开始找X的所有因子(*精华部分),建议举几个例子来理解,如36
for (int i=1;i*i<=X;i++)
{
if (X%i==0)
{
if (i*i==X) // 若为平方根,则判断是否有相同数字的操作只做一次,避免重复
{
n+=isSameFigure(X,i);
}
else
{
n+=isSameFigure(X,i);
n+=isSameFigure(X,X/i);
}
}
}
printf("%d",n);
return 0;
}
关于isSameFigure()的过程我们可以梳理一下,其实很简单:
以36为例子,它的因子是1,2,3,4,6,9,18,36
i=1时,else部分里,第一个isSameFigure的实参是(36,1),第二个是(36,36)
i=2时,第一个isSameFigure的实参是(36,2),第二个是(36,18)
i=3时,第一个isSameFigure的实参是(36,3),第二个是(36,12)
i=4时,第一个isSameFigure的实参是(36,4),第二个是(36,9)
i=6时,第一个isSameFigure的实参是(36,6),第二个是(36,6),存在重复累计情况,所以才有了if里的操作
这样就把因子找全了,不理解的话多尝试几个例子就明白了