2020牛客寒假算法基础集训营5
I I题是个签到题
题目链接:链接
题意:给n个数据,问你第9个数是否是这组数据降序排序的前三,或者第9个数是否 >= m的80%。
解法:就是个,普通的水题,但是有必要注意一下因为可能会出现数据重复的情况,所以哪怕a[9]在整个序列中的大小排了第二,但是第一那个有3个队伍就也不可。我就是在这里折掉的orz
代码:
#include<cstdio>
using namespace std;
int a[15];
int main(void)
{
int cnt = 0;
int n,m;
int maxn;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i ++ )
{
scanf("%d",&a[i]);
}
maxn = a[9];
for(int i = 1; i <= n; i ++ )
{
if(a[i] > maxn)
{
cnt++;
}
}
if(a[9] * 5 >= 4 * m || cnt < 3)
{
printf("Yes\n");
}else printf("No\n");
return 0;
}
J 牛牛战队的秀场
题目链接:链接
题意:在一个半径为r的圆上做一个正n边形,从第 i 号点到第 j 号点最少需要走几条边长。
解法:这也是个,水题。直接求出边长然后求最短的边数。但是我好像精度爆炸了orz这里需要注意的就是,那个边长求的时候,不能直接用三角函数,需要化简一下。不然像我一样wa到怀疑人生怀疑世界orz
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#define sqs 0.000001
#define PI 3.1415926
using namespace std;
int main(void)
{
int n,r;
scanf("%d%d",&n,&r);
int st1,st2;
scanf("%d%d",&st1,&st2);
double len = 2 * r * sin(PI/n);
// printf("%lf\n",sqrt(len));
double ans = len * min(max(st1,st2) - min(st1,st2),min(st1,st2)+n-max(st1,st2));
printf("%lf\n",ans);
return 0;
}
E Enjoy the game
题目链接:链接
题意:一共n张卡牌,先手第一步至少拿1张,最多拿 n - 1 张,接下来每一步双方至少拿一张,最多拿前一个人拿的牌数,拿走最后一张牌的人获胜,如果是先手胜输出“Bob”,否则输出“Alice”。
解法:是个找规律。规律是如果是奇数就直接出Bob,如果是偶数,若偶数中含有奇数的因子那就也是Bob,否则就是Alice。orz
代码:
#include<cstdio>
using namespace std;
bool check(long long now)
{
long long temp = now;
while(temp != 0)
{
if(temp != 1 && temp % 2 == 1) return false;
temp = temp / 2;
}
return true;
}
int main(void)
{
long long n;
scanf("%lld",&n);
if(n % 2 == 1) printf("Bob\n");
else{
if(check(n) == false) printf("Bob\n");
else printf("Alice\n");
}
// if(check(n) == true) printf("")
return 0;
}
B 牛牛战队比赛地
题目链接:链接
题意:给了n个点,求在坐标轴上的某点到这n个点的最大距离最小。
解法:是个三分。需要注意的好像没什么,就是日常注意一下转移的时候的左右边。是照着官方题解现学的orz
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAX_SIZE = 100005;
struct Node{
int x,y;
}map[MAX_SIZE];
int n;
double get(double x)
{
double ans = 0;
for(int i = 1; i <= n; i ++ )
{
double temp = sqrt(map[i].y * map[i].y + (map[i].x - x) * (map[i].x - x));
ans = max(temp , ans);
}
return ans;
}
double operate(double left,double right)
{
double mid,mid1;
for(int i = 0; i < 100 ; i ++ )
{
mid = left + (right - left) / 2;
mid1 = mid - (mid - left) / 2;
if(get(mid) > get(mid1))
{
right = mid;
}else left = mid1;
}
return mid;
}
int main(void)
{
scanf("%d",&n);
for(int i = 1; i <= n; i ++ )
{
scanf("%d%d",&map[i].x,&map[i].y);
}
double ans = operate(-10000,10000);
printf("%lf\n",get(ans));
return 0;
}