可达鸭模拟赛1
数字降级:
思路
根据唯一分解定理,可以知道任意一个大于等于 的数字,都可以找到另一个数字将它除成质数。因此可以直接判断输入的数字是否为质数,如果为质数输出 0 ,否则输出 1 。
数据下,可以使用比较暴力的判断质数的方式,从 遍历到 然后依次判断
#include<iostream>
#include<cstdio>
using namespace std;
int prime(long long num){for(long long i=2;i*i<=num;i++){if(num%i==0){return 0;}}return 1;
}
int main(){long long n;cin>>n;if(prime(n)==1){cout<<0;}else{cout<<1;}return 0;
}
注意事项:
看数据范围!!!(考试就是没看见用的int)!!
分组
思路
考虑有多少个小组分数可以至少为 ,这些小组中必须有一个 。
所以假设 有 个,那么就说明有 个小组分数至少为 ,此时答案增加 (这一步是考虑这些小组对答案的贡献)。
再考虑有多少个小组分数可以至少为 ——这些小组必须有一个 ,并且小组分数至少为 的小组的数量一定小于等于小组分数至少为 的小组数量,所以涉及到一个求 min 的操作。
第一个测试点没有 0,那么每个小组分数肯定都为0
第二个测试点只有 0,那么每个小组分数都为1
第三四个测试点只有 1和 0,那么可以通过1 和 0凑2
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
long long a[N],n,vis[1005];
long long ans=0;
int main()
{cin>>n;for(int i=1;i<=n;i++){cin>>a[i];vis[a[i]]++;}long long m=vis[0]; for(int i=1;i<=1001;i++){if(vis[i]<m){ans+=(m-vis[i])*i;m=vis[i];}}cout<<ans;return 0;
}
抢夺地盘
思路
比较模板的 LIS 问题,从 到 求一次最长上升子序列,然后从 到 求一边最长下降子序列。注意这样的话会有一个重复点 ,所以考虑 是否需要修改。然后分类讨论。
20%数据下可以直接模拟,暴力的LIS可以通过60%数据,使用二分优化的LIS可以拿到满分
#include<iostream>
#include<cstdio>
using namespace std;
int n,pos,a[100005],b[100005],c[100005],p=0;
int main(){//freopen("seize.in","r",stdin);//freopen("seize.out","w",stdout);cin>>n>>pos;for(int i=1;i<=n;i++) cin>>a[i];b[++p]=a[1];for(int i=2;i<pos;i++){if(a[i]>=b[p]) b[++p]=a[i];else{int l=1,r=p,mid=p>>1;while(l!=r){if(a[i]<b[mid]) r=mid;else l=mid+1;mid=(l+r)>>1;}b[l]=a[i];}}if(a[pos]>=b[p]) p++;else a[pos]=1e9+1;int ans=pos-p;p=1;c[p]=a[pos];for(int i=pos+1;i<=n;i++){if(a[i]<=c[p]) c[++p]=a[i];else{int l=1,r=p,mid=p>>1;while(l!=r){if(a[i]>c[mid]) r=mid;else l=mid+1;mid=(l+r)>>1;}c[r]=a[i];}}ans+=(n-pos-p+1);cout<<ans;//fclose(stdin);//fclose(stdout);return 0;
}
闯关
思路:直接模拟就行,让达达先走,在保证距离不超过扔距的前提下交换神器
#include<iostream>
#include<cstdio>
using namespace std;
int a[100005],b[100005],n,m,k,q,cnt=0,flag=0;
int main(){freopen("barrier.in","r",stdin);freopen("barrier.out","w",stdout);cin>>n>>m>>k>>q;for(int i=1;i<=n;i++){cin>>a[i];}for(int i=1;i<=n;i++){cin>>b[i];}int xiaoke=0,dada=0;while(true){if(flag==0){while(dada<n&&b[dada+1]-b[dada]<=m){dada++; } if(dada==n){break;}while(xiaoke<n&&a[xiaoke+1]-b[dada]<=q){xiaoke++;}flag=1;cnt++;}if(flag==1){while(xiaoke<n&&a[xiaoke+1]-a[xiaoke]<=m){xiaoke++; } if(xiaoke==n){break;}while(dada<n&&b[dada+1]-a[xiaoke]<=q){dada++;}flag=0;cnt++;} }cout<<cnt;return 0;
}