丑数
思考过程
其实现在这一题,我还没把代码敲完。但想赶紧把自己的思考过程给记录下来,不然一会儿,一些细节就捕捉不到了。
因为才看了一个“广告”,关于抓住瞬间的灵感,虽然我这纯属是小儿科的思考,但我也坚定地马上打开csdn
我原本用的欧拉筛,将所有的素数标记一下,再将一个数的所有因数进行判断,一直没过,这不重要,因为我看到一个新的代码。
可以先看一下,代码中的x。它不断用x去乘集合中的数, 也就是弹出的值,是集合中的质因数,以及全由质因数相乘所组成的合数。
我就不免发出疑问这个合数难道不会有其他的质因数没在集合中么? 万一有其他质因数乘另一个数也能得到这个合数。
我记忆中一直是“合数是由一个质数和另一个数相乘所得”。
我在用12模拟时发现,
3x4=12=2x6;
都可以分解乘2x2x3
其实我略微思考下,那句话应该是任何一个合数都能分解成若干个质数相乘,
因为既然是质数乘另一个数,这个数是质数,那就是两个质数相乘;是合数,又可以分解乘质数 X 另一个数。
欧拉筛也就是如此啊。我竟然一时间没反应过来。
这样就可以用反证法
证明:
一个数字n,由p1,p2,p3,p4,四个质数相乘所得。
如果存在一个不同于上面四个质数的质数Y,与X的乘积也等于n;
即:
p1·p2·p3·p4=Y·X
那么Y·X也应该能分解成p1·p2·p3·p4
由于Y为不同于P1234的质数,不可分解,
两相矛盾,
故Y不存在
所以不用担心这一点。
那么代码中用优先队列,将x*a[i]放进去是非常巧妙的,
好了,我要去敲代码了。
代码
#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int a[110];
signed main()
{
IOS
int k,n;
cin>>k>>n;
for(int i=0;i<k;i++)
cin>>a[i];
int x=1;//x从1开始,也就是先将集合本身的数存放
priority_queue<int,vector<int>,greater<int> > small;
for(int i=1;i<=n;i++)//弹出第n个就是answer,
{
for(int j=0; j<k ;j++)
{
small.push(a[j]*x);
}
x=small.top();//x后来会是一个合数,
//也就是弹出的值,是集合中的质因数,以及全由质因数相乘所组成的合数
//因为合数全是由集合中的质因数相乘所得,不可能再由其他的质数相乘所得
while(!small.empty()&&small.top()==x)
small.pop();
}
cout<<x<<'\n';
}
可以看看leetcode上丑数II
🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔
😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎
🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪🤪
🤪🤪🤪🤪🤪🤪🤪🤪🤪
🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳🥳
🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣🫣
☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️☠️
💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀💀
偷得浮生片刻闲
当然是片刻啦
不改岂不是显得我太过游手好闲