暴力模拟即可,开始我尝试记录每个‘-’的位置,然后遍历pos数组,枚举0-9,然而这种写法很恶心。那么自然想到了搜索,每次访问到‘-’枚举0-9即可,进入下一次搜索,注意终止条件是当index==9时,因为使用的是1-base。然后剔除一些非法日期即可符合题意,这样能过 。
#include<iostream>
#include<string>
int month[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
bool is_prime(int x)
{
if (x == 0 || x == 1)
return false;
if (x == 2)
return true;
for (int i = 2; i * i <= x; i++)
{
if (x % i == 0)
return false;
}
return true;
}
bool valid_date(int y, int m, int d)
{
int flag = ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0) ? 1 : 0);
if (y < 1 || y>9999)
return false;
if (m < 1 || m>12)
return false;
if (d<1 || d >month[m]+(m==2&&flag?1:0))
return false;
return true;
}
void dfs(int index, std::string& s,int& res)
{
if (index == 9)
{
int y = (s[1] - 48) * 1000 + (s[2] - 48) * 100 + (s[3] - 48) * 10 + (s[4] - 48);
int m = (s[5] - 48) * 10 + (s[6] - 48);
int d = (s[7] - 48) * 10 + (s[8] - 48);
if (valid_date(y, m, d))
{
if (is_prime(d) && is_prime(m * 100 + d) && is_prime(y * 10000 + m * 100 + d))
res++;
}
return;
}
if (s[index] == '-')
{
for (char c = '0'; c <= '9'; c++)
{
s[index] = c;
dfs(index + 1, s,res);
}
s[index] = '-';
}
else
dfs(index + 1, s,res);
}
int main()
{
int n;
std::cin >> n;
std::string s;
while (n--)
{
std::cin >> s;
s = '0' + s;
int res = 0;
dfs(1, s, res);
std::cout << res<<std::endl;
}
}
显然,程序的性能瓶颈,一部分在于试除法判别素数,一部分在一些非法日期作了过多的递归,比如当月份的十位大于1时,于是考虑剪枝
#include<iostream>
#include<string>
#include<unordered_map>
int month[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
std::unordered_map<int, int> cache;
bool is_prime(int x)
{
if (x < 2)
return false;
if (cache.count(x))
return cache[x];
if (x == 2)
return cache[x]=1;
for (int i = 2; i * i <= x; i++)
{
if (x % i == 0)
return cache[x]=0;
}
return cache[x]=1;
}
bool valid_date(int y, int m, int d)
{
int flag = ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0) ? 1 : 0);
if (y < 1 || y>9999)
return false;
if (m < 1 || m>12)
return false;
if (d<1 || d >month[m]+(m==2&&flag?1:0))
return false;
return true;
}
void dfs(int index, std::string& s,int& res)
{
if (s[5] >= '2')
return;
if (s[5]=='1' && s[6] > '2')
return;
if (s[7] > '3')
return;
if (index == 9)
{
int y = (s[1] - 48) * 1000 + (s[2] - 48) * 100 + (s[3] - 48) * 10 + (s[4] - 48);
int m = (s[5] - 48) * 10 + (s[6] - 48);
int d = (s[7] - 48) * 10 + (s[8] - 48);
if (valid_date(y, m, d))
{
if (is_prime(d) && is_prime(m * 100 + d) && is_prime(y * 10000 + m * 100 + d))
res++;
}
return;
}
if (s[index] == '-')
{
for (char c = '0'; c <= '9'; c++)
{
s[index] = c;
dfs(index + 1, s,res);
}
s[index] = '-';
}
else
dfs(index + 1, s,res);
}
int main()
{
int n;
std::cin >> n;
std::string s;
while (n--)
{
std::cin >> s;
s = '0' + s;
int res = 0;
dfs(1, s, res);
std::cout << res<<std::endl;
}
}

京公网安备 11010502036488号