这个月赛都是属于基本题,可能稍微有一点结合,然后我就不会了,我是。
A-矩阵快速幂签到_牛客小白月赛80 (nowcoder.com)
分析
乍一看还以为真的是快速幂,好多小朋友了,然后仔细一看,其实经过移项不难发现,于是乎很显然是等差数列,我们可以求出通项公式,所以答案就是输出%即可。
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=998244353;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll x;
cin>>x;
cout<<(x+1)%mod;
return 0;
}
B-第一次放学_牛客小白月赛80 (nowcoder.com)
分析
模拟+贪心,我们将每个班级的人数存起来(数组和皆可),然后我们遍历如果人数,我们就不停的取,否则说明可以取到。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int n,a[N],m,k;
map<int,int> mp;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]++;
}
int ans=0;
for(auto it:mp){
if(it.second<=n-k) ans=max(ans,it.second);
else ans=n-k;
}
cout<<ans;
return 0;
}
D-又放学辣(进阶)_牛客小白月赛80 (nowcoder.com)
和这里就放一个,数据范围很小,其实很容易,就是可以单纯二分来解决,复杂度是,很显然可以过,我们遍历每个班级,二分一个最小留下来的最大人数,使用型的二分找出最大值,然后把的都求和和比较大小即可,但是加强了数据范围,就要用前缀和来优化,这个其实是一个二分套二分的过程,时间复杂度是,我们使用两个数组分别记录排序前和后的班级人数,下面二分不变,上面二分里面再套一个二分来寻找排完序之后的最小的下标值,这里要注意,如果拖堂的班级人数,要提前减去。但是有的做法,可惜我不会。 代码
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
int n,m,k;
map<int,int> mp;
const int N=1e6+10;
int a[N];
int sum[N];
bool check(int id,int mi){
int ans=0;
for(int i=1;i<=m;i++){
if(i!=id){
ans+=max(0,sum[i]-mi);
}
}
return ans<=k;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m>>k;
memset(sum,0,sizeof sum);
for(int i=1;i<=n;i++){
cin>>a[i];
sum[a[i]]++;
}
for(int i=1;i<=m;i++){
if(n-sum[i]<k) cout<<-1<<" ";
else{
int l=0,r=1e6;
while(l<r){
int mid=l+r>>1;
if(check(i,mid)) r=mid;
else l=mid+1;
}
cout<<l<<" ";
}
}
return 0;
}
代码
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
int n,m,k;
const int N=1e6+10;
int a[N];
int sum[N],res[N];
int pre[N];
bool check(int id,int mi){
int ans=0;
if(sum[id]>mi) ans-=sum[id]-mi;
if(pre[m]<mi) return true;
int l=1,r=m;
while(l<r){
int mid=l+r>>1;
if(pre[mid]<=mi) l=mid+1;
else r=mid;
}
ans+=res[m]-res[l-1]-(m-l+1)*mi;
//cout<<ans<<endl;
return ans<=k;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin>>n>>m>>k;
memset(sum,0,sizeof sum);
for(int i=1;i<=n;i++){
cin>>a[i];
sum[a[i]]++;
pre[a[i]]++;
}
sort(pre+1,pre+m+1);
res[0]=0;
for(int i=1;i<=m;i++){
res[i]=res[i-1]+pre[i];
}
for(int i=1;i<=m;i++){
if(n-sum[i]<k) cout<<-1<<" ";
else{
int l=0,r=1e6;
while(l<r){
int mid=l+r>>1;
if(check(i,mid)) r=mid;
else l=mid+1;
}
cout<<l<<" ";
}
}
return 0;
}