【发布时间】:2020-03-28 08:28:33
【问题描述】:
问题是:
Ramanujan 非常喜欢玩数字游戏。有一天,Ramanujan 和 Anish 玩了一场游戏。 Ramanujan 给了 Anish 一个数字串,并要求他找出所有大小最多为 6 且为素数的不同子串。擅长数学的 Anish 参与了这场比赛,如果他能对 Ramanujan 提供给他的所有输入集给出解决方案,Anish 就赢得了比赛。你的任务是帮助 Anish 赢得比赛。
输入格式
第一行包含 T,测试用例的数量。每个测试用例都包含一个大小为 N 且仅包含整数的字符串。
约束
1
输出格式
对于每个测试用例,打印长度最多为 6 的不同素数子串的总数。
我的代码是 C++: 我创建了一个小于 10^7 的平方根的所有素数的向量和映射,并且初始化映射为 1(1 表示素数,0 表示合数)。 即使为了检查数字是否为素数,我也将其除以仅小于其平方根的素数。 但即使做了所有这些,我也无法通过第二个测试用例(显示因超时而终止)。我只能通过第一个测试用例。我认为我的程序需要很多时间来创建子字符串(使用 substr() 函数)。有什么方法可以降低时间复杂度吗?请回答。
map<long int,int>mp{{2,1},{3,1},{5,1},............................,{3121,1},{3137,1}};
map<long int,int>p;
vector<long int>v{2,3,5,..............3137};
long int c=0;
void check_prime(long int n)
{
long int i;
int flag=-1;
for(i=0;v[i]*v[i]<=n;i++)
{
if(n%v[i]==0)
{
flag=1;
break;
}
}
if(flag==-1)
{
++c;
mp.insert(pair<long int,int>(n,1));
p.insert(pair<long int,int>(n,1));
}
else
{
mp.insert(pair<long int,int>(n,0));
p.insert(pair<long int,int>(n,1));
}
}
int main() {
int t;
string s;
long int n,n1,i,j;
cin>>t;
while(t--)
{
long int i,j;
cin>>s;
for(i=0;i<s.length();i++)
{
int l=s.length()-i;
for(j=1;j<=min(6,l);j++)
{
n=stoi(s.substr(i,j));
if(p.count(n)==0)
{
if(mp.count(n)==1 )
{
if(mp[n]==1 )
{
++c;
p.insert(pair<long int,int>(n,1));
}
else
{
p.insert(pair<long int,int>(n,1));
}
}
else
{
if(n<3162 || n%2==0 || n%5==0)
{
mp.insert(pair<long int,int>(n,0));
p.insert(pair<long int,int>(n,1));
}
else
{
check_prime(n);
}
}
}
}
}
cout<<c<<endl;
p.clear();
c=0;
}
return 0;
}
【问题讨论】:
-
可以看hackerrank的社论。
-
您可以通过查看正在测试的子字符串的最后一位数字来节省一些工作。有多少个以数字“4”结尾的素数?
标签: c++ substring primes substr sieve-of-eratosthenes