其他分享
首页 > 其他分享> > kk的签到题(数据加强版) ---题解

kk的签到题(数据加强版) ---题解

作者:互联网

 题意如上,数据加强版对n的最大值进行了加大,从原来的1000加到了1000000,如果还是用暴力求解的方法的话,那么一共最高500次查询,每次都暴力求解的话,时间复杂度达到了500 * 1e6,也就是5e8,对于计算机计算而言,一般来说计算量达到1e8就大概率会超时(1s时限下)。所以此题我们无法再使用暴力求解。

我们可以想一想,对于每个n是有固定的值的,也就是说,第一个喜欢的数永远是1,第二个永远是2,第三个永远是4,第1000个永远是1666,也就是说,无论如何,值不会改变。按照我们之前暴力求解的思路,我们每次查询都要从1开始重新找,那么每次都有可能要查询100w次,那么显然不合理,这个时候就涉及到了预处理方法,也就是我们使用一个100w的数组,预先记录完100w个数,存下每个喜欢的数的值,在每次查询的时候,直接输出这个下标在数组中的值。这就叫预处理,通俗来讲就是提前处理,用的时候直接查询。这样的话我们只需要一次for循环从1到1000000。时间复杂度为1e6 + 500!

代码如下

#include<bits/stdc++.h> //万能头文件
typedef long long ll;
using namespace std;
int a[1010000];
void pre() { //预处理
	int s = 1; //s为当前的数
	for (int i = 1; i <= 1000000; i++) { //i表示的是第i个喜欢的数,最大到100w
		if (s % 3 != 0 && s % 10 != 3) { // 如果两个条件都不满足,那么说明该数为喜欢的数
			a[i] = s; //存下第i个喜欢的数为s
		}
		else {
			while (s % 3 == 0 || s % 10 == 3) {//否则一直循环,直到满足喜欢的数的条件为止
				s++;
			}
			a[i] = s;
		}
		s++;
	}
}
int main() {
	//ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int t;
	scanf("%d", &t);
	pre();
	while (t--) {
		int n;
		scanf("%d", &n);
		printf("%d\n", a[n]);
	}
	return 0;
}

 

标签:加强版,求解,kk,题解,查询,int,100w,预处理,500
来源: https://blog.csdn.net/qq_51034140/article/details/120577296