题目链接Problem - 1858C - Codeforces
比赛Dashboard - Codeforces Round 893 (Div. 2) - Codeforces
相信这条一定使大多数初学者难堪,但是不要害怕,我来拯救你们!
这题首先我们要明确目标,如果1-n你的数字是1,2,4,8,10...... 这种的话,你就会发现他的分数在逐渐上升,1和2是1,2和4是2,4和8是4,相信我举了这几个例子,你已经知道这题应该要怎么写了。
这条其实我个人感觉就是运用了类似埃氏筛的一个原理(如果你是数学和代码大佬,你可以用一下欧拉筛),我们先暂时不管1,把1放在第一位。从2开始,每个都乘2,例如2,4,6,8........ 这种,每次筛选我们都能把有因子2的数给筛选出来。然后从3再开始,3,6,9,12........ ,但是我们发现6这个数字同时有2和3这个因子,如果按照我刚刚说的来输出,6这个数字肯定会被输出两次,那这样肯定会wa的,所以我们要做的就是,已经出现的数字就不要让他出现第二遍了。
接下来是代码实现
#include <iostream>
#include <cstring>
#include <vector>
#define int long long
#define ll long long
#define endl '\n'
using namespace std;
int t;//放在外面减少运行时间
void solve()
{
int n;
cin>>n;
vector<int> a(n+1);//动态数组比定义在外面的一个大数组运行时间大大减少
a.clear();//每次循环清空数组,防止出现不必要的错误
cout<<"1"<<' ';//像我说的先输出1,不知道建议看下埃氏筛原理
a[1]=1;
for(int i = 2;i<=n;i++)
{
int tmp = i;//从2开始找有因子2的数,以此类推
while(tmp<=n)//防止找的tmp超出范围n
{
if(!a[tmp]) cout<<tmp<<' ';
a[tmp]=1;//防止重复出现
tmp*=2;
}
}
cout<<'\n';
}
signed main(void)
{
std::ios::sync_with_stdio(false);//关闭输入流
cin.tie(0);//关闭输入流
cout.tie(0);//关闭输入流
cin>>t;
while(t--)
{
solve();
}
return 0;
}
文章最后,我想说我把我自己在知乎上的文章转载了,我的知乎是字正腔圆,这样应该还是我自己原创