B
题目大意:
有两个人打羽毛球轮流发球
现在知道这两个人赢的场数
不知道是哪个人先发球
让你输出发球失误可能的次数
思路:
找规律…
写一页草稿纸差不多
就分a+b为奇数的情况与a+b为偶数的情况
奇数的时候比较明显
比如a+b=5的时候
a=5 b=0时答案为2 3
a=4 b=1时答案为1 2 3 4
a=3 b=2时答案为0 1 2 3 4 5
之后同理
奇数的时候是从中间向两边延伸的
找到两个数最大值与n的差值然后长度就是(n-max(a,b)+1)*2
第一个数就是n/2-(n-max(a,b))(找到n/2后减去长度的一半+1就是开头的数字
而偶数的时候比如
a+b=4
a=4,b=0时候答案为2
a=3,b=1时候答案为1 3
a=2,b=2时候答案为0 2 4
开头的第一个数数字跟奇数的时候是一样的就是n-(n-max(a,b))
不过它跳的时候是两格两格跳的
知道规律就很好写了
AC代码:
#include <iostream>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
int a,b;
cin>>a>>b;
int n=a+b;
if(n%2==1){
int ans=2;
int mmax=max(a,b);
ans+=(n-mmax)*2;
cout<<ans<<endl;
int st=n/2-(n-mmax);
for(int i=st;i<st+ans;i++){
cout<<i<<' ';
}
cout<<endl;
}else{
int mmax=max(a,b);
int ans=n-mmax+1;
cout<<ans<<endl;
int st=n/2-n+mmax;
while(ans--){
cout<<st<<' ';
st+=2;
}
cout<<endl;
}
}
return 0;
}
C
题目大意:
给你n个山洞
每个山洞里都有怪物
每个怪物都有一个力量值
只有你的力量值大于怪物的力量值的时候才能打败怪物
打败怪物的时候会获得一点力量值
问你至少需要多少力量值才能打败所有怪物
思路:
先记录每个山洞需要的最小力量值是多少
然后从需要最小力量值的山洞开始打,看打完这个山洞后自己的力量值够不够下一个山洞的力量值,不够就往上加
就差不多模拟的感觉
不过也可以用二分去找边界值
具体看代码
AC代码:
#include <bits/stdc++.h>
using namespace std;
struct node{
int v,k;
}q[100010];
int sum[100010];
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int m=0;m<n;m++){
cin>>q[m].k;//怪物数量
int cnt=0;//进山洞前需要的力量值
for(int i=0;i<q[m].k;i++){
int x;
cin>>x;
if(cnt+i<=x){
cnt=x+1-i;
}
}
q[m].v=cnt;//需要的力量值
}
sort(q,q+n,[](node x,node y){return x.v<y.v;});//按力量值排序
int ans=q[0].v;
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+q[i-1].k;//前缀和记录得分
for(int i=1;i<n;i++){
if(ans+sum[i]<q[i].v){
ans=q[i].v-sum[i];//不够就往上加
}
}
cout<<ans<<endl;
}
return 0;
}