Asia Hong Kong Regional Contest 2016(2021/10/6)


题目链接

B Kattis doors

题目分析与大意

就是在两个球之间找能够通过的最大半径,其实就是求几次点到线段的距离。(直接从代码中看)
关于直线和线段的距离公式参见链接

代码

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;


double R,L,W,Alpha,Beta;

const double pi=acos(-1.0),eps=1e-9,inf=10000.0;

struct Point
{
    double x,y;
    Point()
    {
        x=y=0;
    }
    Point(double _x,double _y)
    {
        x=_x,y=_y;
    }
    Point operator+(Point v)
    {
        return Point(x+v.x,y+v.y);
    }
    Point operator-(Point v)
    {
        return Point(x-v.x,y-v.y);
    }
    double operator*(Point v)
    {
        return x*v.x+y*v.y;
    }
    bool operator==(Point v)
    {
        if(x==v.x&&y==v.y)
            return true;
        else
            return false;
    }
    double len()
    {
        return hypot(x,y);//计算直角三角形斜边长,其中两个参数为两个直角三角形的长度
    }
};

double cross(Point a,Point b)//求向量叉乘
{
    return a.x*b.y-a.y*b.x;
}
double dot(Point a,Point b)//求向量点积
{
    return a.x*b.x+a.y*b.y;
}

double distance_line(Point p,Point a,Point b)
{
	Point v1 = b - a,v2 = p - a;
	return fabs(cross(v1,v2) / v1.len());//cross是v1和v2的叉积
}
double dist_point_to_segment(Point p,Point a,Point b)//点p到线段ab的距离
{
	if(a == b)
		return (p-a).len();
	Point v1 = b - a,v2 = p - a,v3 = p - b;
	if(dot(v1,v2) < 0)	//dot是v1和v2的点积
		return v2.len();
	if(dot(v1,v3) > 0)
		return v3.len();
	return distance_line(p,a,b);
}

double cal(Point a,Point b,Point c,Point d)
{
    return min(min(dist_point_to_segment(a,c,d),
                   dist_point_to_segment(b,c,d)),
               min(dist_point_to_segment(c,a,b),
                   dist_point_to_segment(d,a,b)));
}

double solve()
{
    Point A(-inf,W),B(0,W);
    Point D(L,W),E(inf,W);
    Point G(L,0),H(inf,0);
    Alpha=pi-Alpha,Beta=pi-Beta;
    Point C=D+Point(cos(Alpha)*L,sin(Alpha)*L);
    Point F=G+Point(cos(Beta)*L,sin(Beta)*L);
    double ans=min(L,W);
    ans=min(ans,cal(A,B,C,D));
    ans=min(ans,cal(C,D,F,G));
    ans=min(ans,cal(D,E,F,G));
    ans/=2.0;
    ans=min(ans,R);
    ans=max(ans,0.0);
    return ans;
}

int main()
{
    int t;
    scanf("%lf%lf%lf",&R,&L,&W);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf",&Alpha,&Beta);
        printf("%.9f\n",solve());
    }
    return 0;
}

C Playing with Numbers

题目大意及分析

这道题目就是对形如2a3b这样的数构成的序列进行操作的一个题目,主要就是要分析两个这样的数之间的最小公倍数和最大公因数的关系。

代码

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 5e4+10;

struct num{
    int a,b;
}da[N];

int maxa1[N],mina1[N],maxb1[N],minb1[N];
bool com(num a,num b)
{
    return (a.a*log(2)+a.b*log(3)<b.a*log(2)+b.b*log(3));
}
void solve()
{
    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d%d",&(da[i].a),&(da[i].b));
    }
    sort(da+1,da+1+n,com);

    maxa1[1]=mina1[1]=da[1].a;
    maxb1[1]=minb1[1]=da[1].b;
    for(int i = 2;i <= n;i++)
    {
        maxa1[i] = max(maxa1[i-1],da[i].a);
        mina1[i] = min(mina1[i-1],da[i].a);
        maxb1[i] = max(maxb1[i-1],da[i].b);
        minb1[i] = min(minb1[i-1],da[i].b);
    }

    if(n==1)
    printf("%d %d %d %d\n",maxa1[n],maxb1[n],maxa1[n],maxb1[n]);
    if(n==2)
    {
        printf("%d %d %d %d\n",maxa1[n],maxb1[n],maxa1[n],maxb1[n]);
        printf("%d %d %d %d\n",mina1[n],minb1[n],mina1[n],minb1[n]);
    }
    if(n==3)
    {
        printf("%d %d %d %d\n",maxa1[n],maxb1[n],maxa1[n],maxb1[n]);
        printf("%d %d %d %d\n",da[n].a,da[n].b,da[1].a,da[1].b);
        printf("%d %d %d %d\n",mina1[n],minb1[n],mina1[n],minb1[n]);
    }
    if(n>=4)
    {
        printf("%d %d %d %d\n",maxa1[n],maxb1[n],maxa1[n],maxb1[n]);
        printf("%d %d %d %d\n",maxa1[n],maxb1[n],da[1].a,da[1].b);
        for(int i = 3;i < n-1;i++)
        {
            printf("%d %d %d %d\n",maxa1[n],maxb1[n],mina1[n],minb1[n]);
        }
        printf("%d %d %d %d\n",da[n].a,da[n].b,mina1[n],minb1[n]);
        printf("%d %d %d %d\n",mina1[n],minb1[n],mina1[n],minb1[n]);
    }
}

int main()
{
	int t = 1;
//	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

J Taboo

题目大意及分析

给定n个由01构成的字符串,找到一个由01组成的字符串满足如下情况:1、保证其字串中没有这n个字符串中的任意一个;2、保证这个字符串的长度最长,如果有无限个这样的字符串,则输出-1;3、如果存在多个相同长度的该字符串,则输出字典序最小的那个。
我在做题的时候想到的是用字典树来做,后来才想到光用字典树肯定会漏掉情况,因为字典树考虑的只是前缀,但是按照题目中的意思,所谓的子串肯定不能只是包括前缀,中间的一部分子串也可能会包括上面的n个字符串,因此错误了。
考虑到要进行字符串的匹配,因此可能需要用到ac自动机,这里我之前也是没有怎么涉及过,这道题还需要再学习。

代码

后面补上

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值