zoukankan      html  css  js  c++  java
  • CROCMBTU 2012, Final Round (Online version, Div. 2)笔记

    感觉这次的题目几乎没有算法,都是实现有点烦的题目,代码能力还有待提高.

    D. Building Bridge

    题意:

      一个平面上有4个点A,B,C,D,A点坐标确定为(0,0),B点坐标为(a,y1),C点坐标为(B,y2),C到D点的距离确定为L,求选取哪个y1和y2的组合可以使总距离最小.

    赛时想法:

      当时的情况是C题写的有点慢了,D题剩下40分钟不到,不管是不是心急吧,反正图画出来以后没有什么明确的想法...看着10W的M和N,大脑处于基本空白的状态...坚持到还有20分钟的时候就暂时放弃了...想着就算有了思路也不一定有时间实现了,然后去看别人前面的代码,想要hack赚点分...不过hack还是风险太大了,这次才知道在比赛中看别人的代码是不能复制的,所以样例也没法测试,最后也没有hack,所以总结起来就是最后的时间是被我浪费掉了.

    正确思路:

      结束以后抱着强烈的好奇心就去看别人的解法了...看完第一个人的就傻了...比赛的时候一直想着,由于L是不确定的,所以不能直接算...可是完全没有往枚举y2的方向去想,恍然大悟了...其实就是枚举y2的坐标,然后三分确定y1的坐标.

    代码1:

    View Code
    #include<stdio.h>
    #include<math.h>
    #define maxn 110000
    
    int va1[maxn],va2[maxn],l[maxn];
    
    double dis(int x,int y)
    {
        return sqrt(1.0*x*x+1.0*y*y);
    }
    
    int main()
    {
        int n,m,a,b,lans,rans,i,j,mid1,mid2;
        double min=10000000000;
        while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF)
        {
            for(i=1;i<=n;i++)
            {
                scanf("%d",&va1[i]);
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d",&va2[i]);
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d",&l[i]);
                int st=1,end=n;
                while(st<end-3)
                {
                    mid1=(st+end)/2,mid2=mid1+1;
                    double ans1=dis(a,va1[mid1])+dis(a-b,va1[mid1]-va2[i]);
                    double ans2=dis(a,va1[mid2])+dis(a-b,va1[mid2]-va2[i]);
                    if(ans1<ans2) end=mid1; else st=mid2;
                }
                for(j=st;j<=end;j++)
                {
                    double ans=dis(a,va1[j])+dis(a-b,va1[j]-va2[i])+l[i];
                    if(ans<min)
                    {
                        min=ans;
                        lans=j;
                        rans=i;
                    }
                }
            }
            printf("%d %d\n",lans,rans);
        }
        return 0;
    }

    代码2:

      第一个代码交上去发现时间有点长...后来想到,既然已经枚举y2了,那么一定是在A,B,C三点共线的情况是最好的,所以利用斜率直接2分就可以了,OMG真是弱爆了,引用我们金工老师的话就是:“脑子都僵掉了”.

    View Code
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 110000
    int va1[maxn],va2[maxn],l[maxn];
    
    double dis(int x,int y)
    {
        return sqrt(1.0*x*x+1.0*y*y);
    }
    
    int main()
    {
        int n,m,a,b,lans,rans,i,j;
        double min=10000000000;
        while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF)
        {
            for(i=1;i<=n;i++)
            {
                scanf("%d",&va1[i]);
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d",&va2[i]);
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d",&l[i]);
                double good=a*1.0/b*va2[i];
                j=lower_bound(va1+1,va1+n+1,good)-va1;
                double ans=dis(a,va1[j])+dis(a-b,va1[j]-va2[i])+l[i];
                if(ans<min)
                {
                    min=ans;lans=j;rans=i;
                }
                if(j>=2)
                {
                    double ans=dis(a,va1[j-1])+dis(a-b,va1[j-1]-va2[i])+l[i];
                    if(ans<min)
                    {
                        min=ans;lans=j-1;rans=i;
                    }
                }
            }
            printf("%d %d\n",lans,rans);
        }
        return 0;
    }

    E. Mad Joe


    题意:

      有个人在一个n层的迷宫里走路,刚开始他在第n层的第一个位置,方向向右,然后开始走路,如果途中遇到前面有混凝土墙则转向,如果遇到石头墙,则先撞坏墙(墙变成空)然后再转向,如果在碰到障碍物前遇到脚下是空的情况,则直接进入下一层,问多长时间以后才能到达第一层.

    赛时想法:

      很不好的习惯,不按着顺序做就会觉得不自在,这题当时根本没看...也可以说是被那张图吓到了吧- -.没想到是道模拟..

    正确思路:

      其实就是按照题目的思路模拟,但是由于每行的长度m很大,不能正常的每次++或--,要记录左右边界,每次直接拓展左右边界,这样每行复杂度最多也就是10000.

    代码:

    View Code
    #include<stdio.h>
    char map[110][10010];
    
    int main()
    {
        int n,m,dir,pos,l,r,i,c;
        __int64 ans;
        scanf("%d%d",&n,&m);
        ans=0;
        for(i=1;i<=n;i++)
        {
            scanf("%s",map[i]+1);
            map[i][0]=map[i][m+1]='#';
        }
        dir=1,pos=1;//记录方向,dir=1代表向右,dir=0代表向左,pos代表当前的位置
        for(i=1;i<n;i++)
        {
            c=0;
            l=r=pos;//左右边界一开始等于出发点,然后分别向左右拓展开
            while(1)
            {
                if(dir)
                {
                    while(map[i][r+1]=='.'&&map[i+1][r]!='.')
                        r++;
                    ans+=r-pos+1;
                    pos=r;
                    if(map[i+1][r]=='.')
                    {
                        break;
                    }
                    else if(map[i][r+1]=='+')
                    {
                        map[i][r+1]='.';
                        dir=!dir;
                        c=0;//如果是石头墙,则上次碰到混凝土墙的标记应取消
                    }
                    else if(!c&&map[i][r+1]=='#')
                    {
                        c=1;//如果碰到混凝土墙则标记
                        dir=!dir;
                    }
                    else
                    {
                        printf("Never\n");//碰到2次混凝土墙还没有跳出,说明不可能出去了.
                        return 0;//由于CF是分组测试,可以直接retun跳出,免去不必要的标记.
                    }
                }
                else
                {
                    while(map[i][l-1]=='.'&&map[i+1][l]!='.')
                        l--;
                    ans+=pos-l+1;
                    pos=l;
                    if(map[i+1][l]=='.')
                    {
                        break;
                    }
                    else if(map[i][l-1]=='+')
                    {
                        map[i][l-1]='.';
                        dir=!dir;
                        c=0;
                    }
                    else if(!c&&map[i][l-1]=='#')
                    {
                        c=1;
                        dir=!dir;
                    }
                    else
                    {
                        printf("Never\n");
                        return 0;
                    }
                }
            }
        }
        printf("%I64d\n",ans);
        return 0;
    }

      

  • 相关阅读:
    p4 view mapping及其特殊字符
    Build Release Blogs
    Linux技术blogs
    为什么使用tmux
    linux下安装wine
    PythonDjango的windows环境
    tmux安装
    基于云端的开发平台Team Foundation Service
    linux网络配置之setup命令
    Centos6.2设置静态ip和dns
  • 原文地址:https://www.cnblogs.com/SolarWings/p/2793382.html
Copyright © 2011-2022 走看看