第 46 届 ICPC 国际大学生程序设计竞赛亚洲区域赛(会补)


哎,上海站打的很烂,自己不会的还是太多,还有就是英语真的重要,热身赛就是因为翻译错了,然后题意弄错了

热身赛

热身赛链接

A.Two Point Removal

在这里插入图片描述
在这里插入图片描述
题目大意:就是给你若干点的纵坐标,然后横坐标是1-n,然后在若干点中删除2个,然后使得(0,0)到(n+1,0)距离最短;
思路:先删除一个点,保证删除后使得路线最短,再删除下一个

#include <iostream>
#include <algorithm>
#include<cmath>
using namespace std;
const int M=1e6+7;
#define ll long long
int m;
double v[M];
struct node
{
    int x;
    int y;
}b[M];
double solve(node b1,node b2,node b3)
{
    return sqrt(abs(b1.x-b2.x)*abs(b1.x-b2.x)+abs(b1.y-b2.y)*abs(b1.y-b2.y))+sqrt(abs(b3.x-b2.x)*abs(b3.x-b2.x)+abs(b3.y-b2.y)*abs(b3.y-b2.y))-sqrt(abs(b1.x-b3.x)*abs(b1.x-b3.x)+abs(b1.y-b3.y)*abs(b1.y-b3.y));
}
bool cmp(node a,node b)
{
    return a.x<b.x;
}
int main()
{
    cin>>m;
    for(int i=1; i<=m; i++)
    {
        cin>>b[i].y;
        b[i].x=i;
    }
    int u;
    double maxx=0;
    double sum=0;
    b[m+1].y=0;
    b[m+1].x=m+1;
    for(int i=1; i<=m; i++)
    {
        sum+=sqrt(abs(b[i].x-b[i-1].x)*abs(b[i].x-b[i-1].x)+abs(b[i].y-b[i-1].y)*abs(b[i].y-b[i-1].y));
        if(solve(b[i-1],b[i],b[i+1])>maxx)
        {
            u=i;
            maxx=solve(b[i-1],b[i],b[i+1]);
        }

    }
    b[u].x=1e6;
    sum+=sqrt(abs(b[m].x-b[m+1].x)*abs(b[m].x-b[m+1].x)+abs(b[m].y-b[m+1].y)*abs(b[m].y-b[m+1].y));
    sum-=maxx;
    /* for(int i=0;i<=m+1;i++)
    {
        printf("%d %d\n",b[i].x,b[i].y);
    }
    printf("%.16lf\n",sum);*/
    sort(b,b+m+2,cmp);
    /*for(int i=0;i<=m;i++)
    {
        printf("%d  %d\n",b[i].x,b[i].y);
    }*/
    maxx=0;
    for(int i=1; i<=m-1; i++)
    {

        if(solve(b[i-1],b[i],b[i+1])>maxx)
        {
            u=i;
            maxx=solve(b[i-1],b[i],b[i+1]);
        }

    }
    sum-=maxx;
    printf("%.16lf\n",sum);
    return 0;
}

正式赛

正式赛链接

D.Strange_Fractions

在这里插入图片描述在这里插入图片描述
题目大意:解方程。使得上述p/q=a/b+b/a;
思路:首先需要约分成为最简形式,然后通过约分,你可以得到(a+b)平方=p+2q,a-b的平方=p-2q,因为a,b为整数,所以p+2q和p-2q都是平方数,如果不是输出0 0,然后(sqrt(p+2q)+sqrt(p-2q))/2,就是其中一个数,然后a+b也知道,就可以求出另一个数

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long
const ll M=1e6+7;

int main()
{
    ll m,n;
    ll T;
    ll ans,bns;
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld%lld",&m,&n);
        ll L=__gcd(m,n);
        m/=L,n/=L;
        ans=m+2*n;
        bns=m-2*n;
        ll mm=sqrt(ans);
        ll oo=sqrt(bns);
        if(mm*mm!=ans||oo*oo!=bns)
        {
            printf("0 0\n");
            continue;
        }
        ll qq=(sqrt(ans)+sqrt(bns))/2;
        ll nn=mm-qq;
        printf("%lld %lld\n",min(nn,qq),max(nn,qq));
    }
    return 0;
}

E.Strange_Integers(签到题)

在这里插入图片描述
在这里插入图片描述
题目大意:给你若干数和k,让你计算出可以选出多少数,保证它们之间的距离都大于等于K
思路:排序,去重,遍历,判断

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long
const ll M=1e5+7;
ll s[M],p[M];
int main()
{
    ll m,n;
    ll T;
    ll ans;
    cin>>m>>n;
    for(int i=1;i<=m;i++)
    {
       scanf("%d",&s[i]);
    }
    sort(s+1,s+1+m);
  /*  for(int i=1;i<=m;i++)
    {
       printf("%d",s[i]);
    }*/
    p[1]=s[1];
    int j=2;
    for(int i=2;i<=m;i++)
    {
        if(s[i]!=s[i-1])
        {
            p[j]=s[i];
            j++;
        }
    }
   /*for(int i=1;i<=j-1;i++)
    {
       printf("%d",p[i]);
    }
    */
    ans=1;
    ll bns=p[1];
    for(int i=2;i<=j-1;i++)
    {
        if(p[i]-bns>=n)
            ans++,bns=p[i];
    }
    printf("%lld\n",ans);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值