一道很简单的模拟题,不知为何却足足做了将近2周。。。
一,TLE解法
#include <bits/stdc++.h>
using namespace std;
int f(int n)//返回n的所有数位相加之和
{
int sum = 0;
while(n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
bool s(int n)//如果n是S数,返回1,不是返回0
{
int ttt = n / 2,sn = f(n),st = 0;
//st:n的所有数位相加之和 sn:n的分解质因数后所有数位之和
for(int i = 2; i <= ttt; i++)//分解质因数
{
if(n % i == 0)
{
int fs = 0;//fs记录n最多能被多少个i除
while(n % i == 0) n /= i,fs++;
st += f(i) * fs;
}
}
if(sn == st) return 1;//如果n的所有数位相加之和==n的分解质因数后所有数位之和,返回1
else return 0;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n == 0) break;
for(int i = n + 1; i; i++)//枚举>n的数
{
if(s(i))//判断是否是S数
{
printf("%d\n",i);
break;
}
}
}
return 0;
}
超时原因:分解质因数太慢了!此程序中分解质因数·时间复杂度为O(2*n)
二,AC解法
#include <bits/stdc++.h>
using namespace std;
int f(int n)
{
int sum = 0;
while(n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
bool s(int n)
{
int sn = f(n),st = 0;
for(int i = 2; i <= n / i; i++)//原来要枚举n/2次,现在只需枚举sqrt(n)次即可
{
int fs = 0;
while(n % i == 0) n /= i,fs++;
st += f(i) * fs;
}
if(n > 1) st += f(n);//如果最后n仍没分解完,就直接把它看作质因数中的一个,有一次WA就是因为这一点
if(sn == st) return 1;
else return 0;
}
bool pri(int n)
{
if(n < 2) return 0;
if(n == 2) return 1;
for(int i = 2; i <= n / i; i++)
if(n % i == 0)
return 0;
return 1;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n == 0) break;
for(int i = n + 1; i; i++)
{
if(pri(i)) continue;
//优化,因为题目中说了S数不包括质数,因为质数是没有办法分解的。有一次提交WA就是因为没加这一点
if(s(i))
{
printf("%d\n",i);
break;
}
}
}
return 0;
}
此程序中分解质因数·时间复杂度为O(sqrt(n))