题目地址:牛客小白月赛52
A:略
B:牛牛的身高
从右向左遍历每一位就行
#include<iostream>
#include<cstring>
using namespace std;
char a[10];
int main(){
int t;
while(cin>>t){
while(t--){
a[0] = '0';
scanf("%s",a+1);
int len = strlen(a+1);
if(len == 1 && a[1] - '0' < 5){
cout<<a[1]<<endl;;
}else{
int idx = 100;
for(int i = len; i >= 1; i--){
int temp = a[i] - '0';
if(temp>=5){
a[i-1] = a[i-1] +1;
idx = i-1;
}
}
if(a[0] != '0')
cout<<a[0];
for(int i = 1; i <= len; i++){
if(i <= idx)
cout<<a[i];
else
cout<<0;
}
cout<<endl;
}
}
}
return 0;
}
C:说谎的机器
区间覆盖问题,将2,3,操作转化为1,如果直接每次都循环修改区间的值会超时,这里使用差分数组统计每个区间覆盖的次数,找到最小的就是答案
#include<iostream>
#include<cstring>
#include<climits>
using namespace std;
int b[1000100];
int main(){
int n,m;
while(cin>>n>>m){
memset(b,0,sizeof(b));
int op;
int ans,mi;
int o = m;
while(m--){
cin>>op;
if(op == 1){
int x,y;
cin>>x>>y;
b[x]++;
b[y+1]--;
}
if(op == 2){
int x;
cin>>x;
b[x]++;
}if(op == 3){
int x;
cin>>x;
b[1]++;
b[x+1]--;
}
}
mi = INT_MAX;
for(int i = 1; i <= n; i++){
b[i] = b[i] + b[i-1];
//cout<<b[i]<<endl;
mi = min(mi,b[i]);
}
ans = 0;
for(int i = 1; i <= n; i++){
if(b[i] == mi)
ans ++;
}
cout<<o-mi<<" "<<ans<<endl;
}
return 0;
}
D:环上食虫
二分答案的最大值最小化模板题,直接二分所有奶油含量然后check一下是否满足饱腹值修改对应区间就行,这题建议直接开搞,
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 100;
int a[N];
int b[N];
//二分答案
int n,s;
bool check(int x){
int sum = 0;
for(int i = 1; i <= 2*n; i++){
if(b[i] <= x){
sum += a[i];
if(sum >= s)
return true;
}else
sum = 0;
}
return false;
}
int main(){
long long sum = 0;
cin>>n>>s;
for(int i = 1; i <= n; i++){
int t;cin>>t;
a[i] = a[i + n] = t;
sum += a[i];
}
for(int i = 1; i <= n; i++){
int t;cin>>t;
b[i] = b[i + n] = t;
}
if(sum < s){
puts("-1");
return 0;
}
int l = 1,r = 1e9;
while(l < r){
int mid = (l + r) >> 1;
if(check(mid)){
r = mid;
}else{
l = mid + 1;
}
}
printf("%d\n",l);
return 0;
}
E:分组求对数和
两个队列,each表示每个小朋友的数字,sum表示所有小朋友的数字,分别从小到大排序,然后枚举每一个值v 去找所有y>=k-v的情况,然后减去同一个人的组合就行
#include<iostream>
#include<vector>
#include<algorithm>
#define mod 998244353
using namespace std;
vector<int> each[1000010];
vector<int> sum;
int n,k;
int main(){
scanf("%d %d",&n,&k);
int m;
int a;
for(int i = 0; i < n; i++){
scanf("%d",&m);
for(int j = 0; j < m; j++){
scanf("%d",&a);
each[i].push_back(a);
sum.push_back(a);
}
sort(each[i].begin(),each[i].end());
}
sort(sum.begin(),sum.end());
long long ans = 0;
for(int i = 0; i < n; i++){
m = each[i].size();
for(int j = 0; j < m; j++){
int v = each[i][j];
int y = k - v;
ans += (sum.end() - upper_bound(sum.begin(),sum.end(), y - 1))-
(each[i].end() - upper_bound(each[i].begin(),each[i].end(),y-1));
}
}
ans /= 2;
cout<<ans%mod<<endl;
return 0;
}