nyojb 2357

http://acm.nyist.me/JudgeOnline/problem.php?id=2357

2357: 插塔憋憋乐

时间限制: 1 Sec  内存限制: 128 MB
提交: 50  解决: 9
[提交][状态][讨论版]

题目描述

众所不知,LLM是一位红警3大佬,打的非常厉害,但是曾经也是一位萌新,喜欢在家里放防御塔,然后攒单位。现在是这样的:
LLM有一个半径为R的基地,他想放一些防御塔,让任何一个敌方单位在进入自己基地的开始就受到防御塔的攻击,由于LLM希望敌人会顶着防御塔的攻击伤害自己,所以他希望任何一个敌人进入自己基地的时候就立刻受到至少两个防御塔的攻击,现在已知防御塔的防御半径为r,为了简化问题,我们假设:
1.如果一个敌人经过两个防御塔的防御的范围相切的点(如图所示),会受到两个防御塔的攻击,这里受到两个防御塔的伤害

2.不需要保证基地内部受到保护,只要保证敌人在进入基地时受到防御塔攻击即可

请问最少需要几个防御塔

输入

每个测试文件少于1000组测试样例

每组测试样例包含两个整数R,r

1<=R,r<=500

输出

输出仅包含一个数字,代表需要的防御塔数量

样例输入

1 1

样例输出

2


最后思路对了可惜还是WA了,一开始根本没看懂题意好吗我以为是只有在交点上才是双倍伤害,其实是在相交的区域内都是,我们只用考虑边界就好了,要想用一个塔覆盖最大的边界,
也就是使得覆盖更大的弧长,显然弦长越大弧长越大,弦长最大就是r,此时可以求出对应的弧长为多少,也就是一个塔的最大覆盖长度。题目要求双倍,但是直接算一圈之后再*2是错误的,
可能有些区域会覆盖超过两次造成浪费,我们应该把这个圈看做是一条线,题目要求转化为覆盖这条线上每个点两次,也就是覆盖双倍长度的这条线上一次即可更优。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 double PI=acos(-1.0);
 4 int main()
 5 {
 6     int n,m,i,j,k;
 7     int R,r;
 8     while(cin>>R>>r){
 9         double C=2*PI*R;
10         if(r>=R){puts("2");}
11         else{
12             double x=2*R*asin((double)1.0*r/R);
13             cout<<(int)(ceil(2*C/x))<<endl;
14             //cout<<(int)(ceil(C/x))*2<<endl;
15         }
16     }
17     return 0;
18 }
 
原文地址:https://www.cnblogs.com/zzqc/p/7464802.html