好数
虽然不是13号考的那批人,但是还是扔一个暴力题解在这里。
首先数据范围\(n\le 10^7\),就算纯粹暴力去做也只是\(O(nlogn)\),也就是直接从1到n去枚举。秉持着暴力就是要优化细节的精神,对题目进行一个分析,发现无论如何,个位数必须是奇数,否则必然不满足条件,那么优化手段就显而易见了:枚举只枚举奇数。直接把时间复杂度砍一刀成为\(O(\frac{n}{2}log\frac{n}{2})\)。实际优化性能如何呢?在我机子上跑,从\(1\)完全数到\(10^7\)需要0.08秒,而只枚举奇数就能变成0.05秒,要知道对于暴力来说,就算是0.03秒也是一种非常要命的资源。
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n, cnt = 0;
n = 10000000;
//scanf("%d", &n);
for(int i=1; i<=n; i+=2)
{
int temp = i;
int eo = 1, is = 1; // 0为偶数,1为奇数
while(temp>0)
{
int c = temp % 10;
temp /= 10;
if(c%2 != eo)
is = false;
if(!is)
break;
eo = !eo;
}
if(is)
cnt++;
}
printf("%d\n", cnt);
return 0;
}
至于如果数据范围变大要怎么做呢?我在此之前思考过一个思路:由于每一个位置可用的数字其实是固定的,奇数位只能是13579(5个),偶数位只能是02468(5个),首位数字如果是偶数则只能用2468(4个)。因此可以基于排列组合的计算方式处理掉绝大部分数据。例如查询2024,就可以通过计算\(5+4\times5+5\times5\times5 = 150\)获得前面的数字(即1~999),随后可以通过相似的计算得到1000~2000的数据,然后继续分治得到2000~2020的数据,最终再直接枚举2020~2024的数据,即使面对\(1\le n\le 10^{100}\)也不可能爆时间。(拍胸脯)
但是下面的程序我就不想写了,因为已经写红温了。
标签:10,正经,暴力,int,题解,枚举,好数 From: https://www.cnblogs.com/ComputerEngine/p/18134008