牛客周赛 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) 0
            cout<<11-(k+1);
    }
    else //判断点是否落在坐标轴上 
    {
        if(k>=11) 
		    cout<<0<<endl;
        else //(10,0) 1
		    cout<<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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值