本文主要是介绍牛客周赛 Round 16 IOI (B、C题解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
B-小美打靶
一、题目要求
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
小美在训练场打靶,靶一共有 10 环,靶的中心位于 (0,0),如果打中的位置在以靶心为圆心,半径为 1 的圆内,则得 10 分,之后每向外一圈分数减 1,直到 1 分,每圈的半径都比上一圈大 1。即如果打中的位置在以靶心为圆心,半径为 i的圆内,则得 11−i分。
如果打中的位置不在任何一圈内,则得 0 分。
输入描述:
一行两个整数 x,y表示打中的位置坐标。 0≤x,y≤10
输出描述:
输出一个整数,表示得分。
示例1
输入
1 0
输出
10
示例2
输入
1 1
输出
9
二、思路
第一种方法:求出点(x,y)到(0,0)的距离,即double dis=sqrt(x*x+y*y); int k=(int)dis;
double s=dis-k*1.0;
1.先特判当x=0并且y=0的时候,输出10;
2.如果s=0,则说明该点落在坐标轴上,如果k>=11,输出0,否则输出11-k;如果s!=0,如果k+1>=11,则输出0,否则输出11-k-1;
第二种方法:int t=x*x+y*y;当t<=i*I的时候,直接输出11-i;
三、代码
第一种方法
#include <bits/stdc++.h>
using namespace std;
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int x,y;cin>>x>>y;if(x==0&&y==0) {cout<<10;return 0;}double dis=sqrt(x*x+y*y);int k=(int)dis;double s=dis-k*1.0;if(s!=0.0){if(k+1>=11) cout<<0<<endl;else//(10,1) 0cout<<11-(k+1);}else //判断点是否落在坐标轴上 {if(k>=11) cout<<0<<endl;else //(10,0) 1cout<<11-k<<endl;}return 0;
}
第二种方法
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
void solve()
{int x,y;cin>>x>>y;int i,j,f=0;int t=x*x+y*y;for(i=1;i<=10;i++){if(t<=i*i){f=1;cout<<11-i<<endl;break;}}if(f==0)cout<<0<<endl;
}
signed main()
{int t=1;while(t--){solve();}return 0;
}
C-小美打怪
一、题目要求
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
小美在玩游戏,游戏中有 n 个怪物,怪物的血量为 hi,攻击力为 ai。小美的血量为 H,攻击力为 A,小美可以击败血量和攻击力都小于自己的怪物,并且打败后血量降为怪物的血量,攻击力降为怪物的攻击力。小美想知道最多可以打败多少怪物。
输入描述:
第一行三个整数 n,H,A分别表示怪物的数量,小美的血量,小美的攻击力。 第二行 n 个整数 hi,表示怪物的血量。 第三行 n个整数 ai,表示怪物的攻击力。 1≤n≤10^3 1≤ai,hi,H,A≤10^9
输出描述:
输出一个整数表示答案。
示例1
输入
3 4 5
1 2 3
3 2 1
输出
1
说明
最多只能击败一个怪物。
二、思路
1.排序,将血量从大到小进行排序,如果血量相等,攻击力高的放在前面
2.利用01背包思维,每次都可以选择放或者不放,每一步都走最优策略
3.利用f[i]记录第i个怪物下面有几个连续递减的血量和连续递减的攻击力的怪物的数量
4.f[i]的存储,是利用当第i个怪物(i=n;i>=1;i--),和i下面的怪物(j=i+1;j<=n;j++) 进行攻击力和血量的比较,只有当第i个怪物的血量高和攻击力都大于等于第j个怪物的时候,才能进行记录f[i]=max(f[i],f[j]+1),否则f[i]默认为0
例如 样例
5 10 9
10 2 8 9 3
8 7 6 5 4
f[i]记录的是,第i个字符有几个q[i].a连续递减,且q[i].h连续递减的数的个数
例如 10 8,9 5,3 4 ;10 9 3连续递减,8 5 4也连续递减
i=5 f[5]=0;
i=4 f[4]=0;
i=3 f[3]=max((f[3],f[4]+1))=(0,1)=1;
i=2 f[2]=max(f[2],f[4]+1)=(0,1)=1;
i=1 f[1]=max(max(f[1],f[2]+1),max(f[1],f[3]+1),max(f[1],f[4]+1),max(f[1],f[5]+1))
=max(2,2,1,1)=2;
三、代码
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
int n,H,A;
int f[N];
struct node
{int h,a;
} q[N];
bool cmp1(node l,node r)
{if(l.h==r.h)return l.a>r.a;return l.h>r.h;
}
void solve()
{cin>>n>>H>>A;int i,j,k=0,g;for(i=1; i<=n; i++){cin>>q[i].h;//血量 }for(i=1; i<=n; i++){cin>>q[i].a;//攻击力}sort(q+1,q+1+n,cmp1);//血量高的放在前面,如果血量相同,攻击力高的放在前面for(i=n;i>=1;i--)//i=3{for(j=i+1;j<=n;j++)//j=4,5;{if(q[i].a>q[j].a&&q[i].h>q[j].h){f[i]=max(f[i],f[j]+1);//f[3]=max(f[3],f[4]+1);f[3]=max(f[3],f[5]+1)}}}int ans=0;for(i=1;i<=n;i++){if(H>q[i].h&&A>q[i].a){ans=max(ans,f[i]+1);}}cout<<ans<<endl;
}
signed main()
{int t=1;while(t--){solve();}return 0;
}
这篇关于牛客周赛 Round 16 IOI (B、C题解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!