携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
题目描述:
欢迎来到交界之地,褪色者。
恶名昭彰的BOSS“接肢”葛瑞克通过接肢来提升自己的力量,但是最初的葛瑞克十分弱小,接肢数量仅为可怜的1。接下来褪色者会和葛瑞克进行战斗。
假设褪色者面对葛瑞克战败后,再一次挑战葛瑞克时,葛瑞克会在自己原来的身体上通过接肢加强自己的力量,而接肢的数量是以指数递增的。比如褪色者第二次挑战时(假设褪色者不可能第一次就打败葛瑞克),接肢的数量就是第一次的数量 * 2,第三次挑战就是第二次的数量 * 3,以此类推。
褪色者通过攻击来解肢击败葛瑞克,而褪色者的攻击伤害只有质数才会对BOSS造成伤害,合数的攻击对于BOSS无效。且每次攻击伤害都只能从2开始,除非本次攻击无法完全整数解肢(比如接肢数量为21时,伤害为2无法解肢,只有伤害增加到3时才可以攻击BOSS解肢,攻击后接肢数量为7),那么就会伤害增加一点继续攻击BOSS。
当葛瑞克的接肢数量回到最初的起点的时候,即为战胜BOSS。
输入格式:
题目给出褪色者最终战胜葛瑞克所挑战的次数n。
输出格式:
题目要求你输出战胜葛瑞克时,褪色者的攻击的伤害a和伤害a的攻击次数b,a和b之间用空格隔开。并且每一组伤害独占一行输出,且每一行依次递增的输出伤害。
数据范围:
2 ≤ n ≤ 106
输入样例:
5
输出样例:
2 3
3 1
5 1
代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
思路分析:
这道题目看起来十分的懵逼,但是细看你会发现,这其实就是让你输入一个数,求1~这个数的所有数的质数和,然后输出这些数的次数
但是肯定不能从1
这个数每个数都算一遍,这太麻烦了,所有要用筛法
代码如下:
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int N = 1e6 + 10;
int cnt, primes[N];
bool st[N];
//素数数组
void getprimes(int n) {
for (int i = 2; i <= n; i++) {
if (!st[i]) {
primes[cnt++] = i;
for (int j = i; j <= n; j += i) st[j] = true;
}
}
}
int main() {
getprimes(1e6);
int n;
cin >> n;
int cnt = 1;
int cur = 2;
int exp = 2;
int idx = 0;
map<int, int> mp;
do {
if (cur % primes[idx] == 0) {
cur /= primes[idx];
mp[primes[idx]]++;
idx = 0;
}
else
idx++;
// 如果回到了1,证明被战胜了
if (cur == 1) {
cnt++;
cur = 1;
// 接肢的数量是以指数递增的
cur *= (++exp);
}
} while (cnt != n);
// 输出结果
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++)
cout << it->first << " " << it->second << endl;
return 0;
}
结果如下:
PS:成功解题=理清思路+一定的技巧~