zoukankan      html  css  js  c++  java
  • 牛客练习赛48 D 小w的基站网络

    链接:https://ac.nowcoder.com/acm/contest/923/D
    来源:牛客网

    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    输入

    复制
    5
    -1 1
    -1 5
    1 5
    0 2
    2 2
    5

    输出

    复制
    4
    6
    8
    4
    0

    说明

    如图所示,小w所在的基站为5号基站
    示例2

    输入

    复制
    5
    -1 1
    -1 5
    1 5
    0 2
    2 2
    1

    输出

    复制
    0
    -1
    -1
    -1
    -1

    说明

    如图所示,小w所在的基站为1号基站。
    由于1号基站没有出边,所以除了到自己的最小代价为0,无法到达其他基站。
    示例3

    输入

    复制
    5
    -2 2
    2 2
    1 1
    -1 1
    1 1
    3

    输出

    复制
    4
    -1
    0
    2
    -1

    说明

    如图所示,小w所在的基站为3号基站,注意3号基站与2号5号基站的特征向量的叉积为0,所以没有边相连。
    同理1号基站与4号基站也无边相连。

    备注:

    由于输入量和输出量比较大,请勿使用cin,cout进行输入输出。
    本题不会卡常数,不用特地使用输入输出挂。

    思路:

    题意:

    t=|x1*y2-x2*y1|;

    输出基本点(第k个点)到其他各点最小的t值,因为基本点可以途经其他点最后到达目标点,如果无法到达目标点那么输出-1,自己到达自己则输出0,否则输出t值

    步骤:

    1.讲点按照与x正方向轴的夹角(点都在x轴的上半部分,点的y值均大于0)由小到大排个序(操作就在cmp中)

    2.然后遍历到所在的点,这个点之前的点输出的dp值均为-1,因为x1*y2-x2*y1<0

    3,从该点之后的点进行操作

    4.如果suan(start,i)==0,那么该点对应为-1,直接下一个数

    5.每当该点a可以到达的时候,就把该点存储起来,然后遍历下一个点b,从基本点到b的t值如果>基本点到a的最小t值加a与b的t,那么就动态更新基本点到b的值

    6.最后输出每个点的dp值即可。


    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e6+5;
    struct node
    {
        ll x,y; int pos;
    }s[maxn];
    bool cmp(const node &x,const node &y)
    {
        long long temp=x.x*y.y-x.y*y.x;
        if(temp)
        {
            return temp>0;
        }
        else
        {
            return x.x*x.x+x.y*x.y>y.x*y.x+y.y*y.y;
        }
    }
    ll suan(int i,int j)
    {
        return s[i].x*s[j].y-s[j].x*s[i].y;
    }
    ll dp[maxn]; int sta[maxn];
    int main()
    {
        int n,pos,start,top=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld %lld",&s[i].x,&s[i].y);
            s[i].pos=i;
        }
        memset(dp,-1,sizeof(dp));
        sort(s+1,s+1+n,cmp);
        scanf("%d",&pos);
        for(int i=1;i<=n;i++){
            if(s[i].pos==pos)
            {
                start=i;
                break;
            }
        }
        sta[top=1]=start; dp[pos]=0;
        for(int i=start+1;i<=n;i++)
        {
            if(suan(start,i)==0) continue;
            while(top>1&&suan(sta[top-1],sta[top])==0) --top;//防止经过一系列出栈后,栈顶点与栈顶的下一个元素的t值为0.
            while(top>1&&suan(sta[top],i)+dp[s[sta[top]].pos]>=suan(sta[top-1],i)+dp[s[sta[top-1]].pos]) --top;
            dp[s[i].pos]=dp[s[sta[top]].pos]+suan(sta[top],i);//更新数值
            sta[++top]=i;//栈的作用
        }
        for(int i=1;i<=n;i++)
        {
            printf("%lld
    ",dp[i]);
        }
        return 0;
    }
  • 相关阅读:
    CodeForces
    CodeForces
    springboot 入门七-静态资源处理
    springboot 入门六-多环境日志配置
    springboot 入门五-日志一
    springboot 入门四-时间类型处理
    springboot 入门三- 读取配置信息二(读取属性文件方式)
    springboot 入门二- 读取配置信息一
    springboot 入门一 hello world!
    SVN提交小结(转)
  • 原文地址:https://www.cnblogs.com/lusiqi/p/11604906.html
Copyright © 2011-2022 走看看