GESP 2023.12 五级 A题-小杨的幸运数

题目大意(全凭记忆)

小杨的幸运数
小杨认为大于 a 的完全平方数以及完全平方数的倍数是他的幸运数
对于 x,小杨每次可以把 x 加一 
对于 nx,判断每个 x 是不是小杨的幸运数
如果是,输出“lucky” 
如果不是,至少进行几次操作把 x 变成他的幸运数
a, n, x <= 1e6 + 1

思路

在我看到数据范围以及平方数集合的时候,脑海里就已经开始构思(胡思乱想)怎么打表列出所有的情况。

再查找到需要的那项。大概算了一下,要将近1e7的大小。由于前面的一堆选择题都是让人判这个二分对不对,那个二分对不对(满满的善意(不是),就很自然的想到了二分查找。

然后就开始埋头码代码~~

70分代码

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
const int mx = 1000;
int a, n;
int lc[N], len;
bool vis[N];

void lck() {
	int f = sqrt(a);
	if (f * f < a) f ++;
	for (int i = f; i <= mx; ++ i) {
		int f = i * i;
		for (int j = f; j <= N; j += f) {
			if (vis[j]) continue;
			else {
				vis[j] = true;
				lc[++ len] = j;
			}
		}
	}
	sort(lc + 1, lc + len + 1);
}

int flck(int l, int r, int aim) {
	if (l == r) return lc[l];
	int mid = (l + r) >> 1;
	if (lc[mid] >= aim) return flck(l, mid, aim);
	else return flck(mid + 1, r, aim);
}

int main() {
	cin >> a >> n;
	lck();
	
	while (n --) {
		int x; cin >> x;
		int lk = flck(1, len, x);
		if (lk == x) cout << "lucky\n";
		else cout << lk << endl;
	}
	return 0;
}

如果和我一样去考5级的话,也许不会被卡吧。我被卡了。

错误分析

看到70分之后,会有一点点茫然,思路没问题呀?

再去瞅了一眼数据a, x <= 1000001。这个1,有问题。

再一想10000001000的平方,但是多出来了1就有一部分数据有可能你枚举不到!

就是唯一的一个1000001,也在题目的范围内。

一旦a=100001且x=1000001,你就被卡掉了。因为你枚举不到1002001这个幸运数(也可能是其他的对不对)

当你把mx设为1001时,1002001就可以被枚举到,也就覆盖了题目的所有情况。

AC代码

#include <bits/stdc++.h>
using namespace std;

const int N = 2e6 + 10;
const int mx = 1010;
int a, n;
int lc[N], len;
bool vis[N];

void lck() {
	int f = sqrt(a);
	if (f * f < a) f ++;
	for (int i = f; i <= mx; ++ i) {
		int f = i * i;
		for (int j = f; j <= N; j += f) {
			if (vis[j]) continue;
			else {
				vis[j] = true;
				lc[++ len] = j;
			}
		}
	}
	sort(lc + 1, lc + len + 1);
}

bool findd(int l, int r, int aim) {
	if (l < r) return false;
	int mid = (l + r) >> 1;
	if (lc[mid] == aim) return true;
	else if (lc[mid] >= aim) return findd(l, mid - 1, aim);
	else return findd(mid + 1, r, aim);
}

int flck(int l, int r, int aim) {
	if (l == r) return lc[l];
	int mid = (l + r) >> 1;
	if (lc[mid] >= aim) return flck(l, mid, aim);
	else return flck(mid + 1, r, aim);
}

int main() {
	cin >> a >> n;
	lck();
	
	while (n --) {
		int x; cin >> x;
		int lk = flck(1, len, x);
		if (lk == x) cout << "lucky\n";
		else cout << lk << endl;
	}
	return 0;
}

结语

      ~~如果对你有帮助的话,点个赞吧(〃'▽'〃)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值