写在前面
这两道题写起来有点意思,不能单纯的暴力模拟,需要找寻他们之间的规律,也是卡了我好一会才写出来
T3473(丑数)
来源
https://www.jisuanke.com/problem/T3473
题意
给定一个素数集合,他们都是作为丑数的因子,从这个集合里面寻找第k个丑数
思路
为了找第 i i i 个丑数,那么一定要比第 i − 1 i-1 i−1 个丑数大,而且是最小的那一个
- 可以发现比 i − 1 i-1 i−1 大的丑数一定是比 i − 1 i-1 i−1 小的丑数乘某个质数得到的
- 因此我们可以枚举质数,然后枚举丑数,直到大于第 i − 1 i-1 i−1 个丑数,记录一下
- 找到所有的符合条件的丑数以后,找出最小值,那么这个最小值就是第 i i i 个丑数
编程
int a[104],f[N],s[N];//f数组存丑数,s数组存丑数的下标
void solve(){
int n,m;
cin >> n >> m;
for(int i=1;i<=n;++i) cin >> a[i];
f[0]=1;//边界条件
for(int i=1;i<=m;++i){
int minn=INT_MAX;//最好定义大一点
for(int j=1;j<=n;++j){
while(a[j]*f[s[j]]<=f[i-1]) s[j]++;
minn=min(a[j]*f[s[j]],minn);
}
f[i]=minn;
}
cout << f[m];
return ;
}
T1271(完美k倍子数组)
来源
https://www.jisuanke.com/problem/T1271
题意
给定一个数组和一个整数k,从这个数组找到最长的完美子数组,并输出他的长度(完美子数组定义:任意两个元素相加都为k)
思路
我们先考虑可能是完美子数组的情况,总共有3种情况:
- 当前元素是 k k k 的倍数
- 若k为偶数,当前元素 % k k k 等于 k k k 的一半
- 仅仅只有 2 2 2个不同元素相加等于 k k k 的倍数
先比较前两者的大小,找出最大值,判断这个最大值是否大于2,满足则直接输出即可
反之判断是否有 2 2 2个不同元素相加等于 k k k 的倍数,满足则输出2
都不满足输出-1
编程
void solve(){
int n,k;
cin >> n >> k;
int flag=0;//判断2个不同元素相加等于k的倍数
int sum=0,s=0;
map<int,int> m;//标记
for(int i=1;i<=n;++i){
int x;cin >> x;
if(x%k==0) s++;
if(x%k*2==k) sum++;
if(!flag){
x%=k;
if(m[k-x]) flag=1;
m[x]=1;
}
}
int ans=max(sum,s);
if(ans>=2) cout << ans;
else if(flag) cout << 2 << endl;
else cout << -1 << endl;
return ;
}