zoukankan      html  css  js  c++  java
  • Codeforces 1087C Connect Three (思维+模拟)

    题意:

    网格图选中三个格,让你选中一些格子把这三个格子连起来,使得选中的格子总数最小。最后输出方案

    网格范围为1000

    思路:

    首先两点间连起来最少需要的格子为他们的曼哈顿距离

    然后连接方案一定是曼哈顿距离最短的两个点先连上,然后第三个点再接过去

    然后题目就是求第三个点接到的那个点pos,答案就是path(a,pos)+path(b,pos)+path(c,pos)

    求pos有两种方法

    方法一:O(n2)

    1e6枚举pos求最短即可,也能过

    方法二:O(n)

    首先第三个点一定在前两个点组成的矩形之外的,(不然他就不是第三个点了)

    POS一定在前两个点组成的矩形的边界上,也是枚举即可。。

    我写臭了。。还分了八个象限两种情况写的,可以参考一下添加路径的代码

    其实比赛就是这样,口嗨能过就赶紧写,想优化说不定会花更长时间

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 2e6+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    vector<PI>ans;
    PI a[4];
    int d(PI a, PI b){
        return abs(a.fst-b.fst)+abs(a.sc-b.sc);
    }
    void link(PI a, PI b){
        int x = a.fst;
        int y = a.sc;
        int dx,dy;
        //printf("a:%d %d
    b:%d %d
    ",x,y,b.fst,b.sc);
        while(make_pair(x,y)!=b){
            if(b.fst==x)dx=0;
            else dx=abs(b.fst-x)/(b.fst-x);
            if(b.sc==y)dy=0;
            else dy=abs(b.sc-y)/(b.sc-y);
    
            if(dx!=0)x+=dx;
            else y+=dy;
            //printf("yeh:%d %d
    ",x,y);
            if(x==b.fst&&y==b.sc)break;
            ans.pb(make_pair(x,y));
        }
        return;
    }
    bool cmp(PI a, PI b){
        if(a.fst==b.fst)return a.sc<b.sc;
        return a.fst < b.fst;
    }
    int main(){
        for(int i = 1; i <= 3; i++){
            scanf("%d %d", &a[i].fst, &a[i].sc);
            ans.pb(a[i]);
        }
    
        int d1 = d(a[1],a[2]);
        int d2 = d(a[1],a[3]);
        int d3 = d(a[2],a[3]);
        int dd = min(min(d1,d2),d3);
        if(dd==d3){
            swap(a[1],a[3]);
        }
        else if(dd == d2){
            swap(a[2],a[3]);
        }
        PI pos=make_pair(-1,-1);
        int x1 = min(a[1].fst,a[2].fst);int x2=max(a[1].fst,a[2].fst);
        int y1 = min(a[1].sc,a[2].sc);int y2=max(a[1].sc,a[2].sc);
        for(int i = 1; i <= 3; i++){
            //printf("i:%d %d %d
    ",i,a[i].fst,a[i].sc);
        }
        //printf("%d %d %d %d
    ",x1,x2,y1,y2);
        for(int dx = 0; dx <= 1000; dx++){
            int x = a[3].fst+dx;
            int y = a[3].sc;
            //printf("  %d %d %d
    ",dx,x,y);
            if(x>=x1&&x<=x2&&y>=y1&&y<=y2){
                pos = make_pair(x,y);break;
            }
            x = a[3].fst-dx;
            if(x>=x1&&x<=x2&&y>=y1&&y<=y2){
                pos = make_pair(x,y);break;
            }
        }
        //printf("   %d %d
    ",pos.fst,pos.sc);
        for(int dy = 0; dy <= 1000; dy++){
            int x = a[3].fst;
            int y = a[3].sc+dy;
            if(x>=x1&&x<=x2&&y>=y1&&y<=y2){
                pos = make_pair(x,y);break;
            }
            y = a[3].sc-dy;
            if(x>=x1&&x<=x2&&y>=y1&&y<=y2){
                pos = make_pair(x,y);break;
            }
        }//printf("   %d %d
    ",pos.fst,pos.sc);
        if(pos.fst==-1){
            PI b[5];
            b[1] = make_pair(x1,y1);
             b[2] = make_pair(x1,y2);
              b[3] = make_pair(x2,y1);
               b[4] = make_pair(x2,y2);
            int ttmp = inf;
            int pp = -1;
            for(int i = 1; i <= 4; i++){
                if(ttmp>d(a[3],b[i])){
                    ttmp=d(a[3],b[i]);
                    pp=i;
                }
            }
            pos=b[pp];
        }
        //printf("   %d %d
    ",pos.fst,pos.sc);
        //printf("  %d
    ",ans.size());
        link(a[1],pos);
        link(a[2],pos);
        link(a[3],pos);
        
        if(pos!=a[1]&&pos!=a[2]&&pos!=a[3])ans.pb(pos);
        printf("%d
    ",ans.size());
        sort(ans.begin(), ans.end(), cmp);
        for(int i = 0; i < (int)ans.size(); i++){
            printf("%d %d
    ",ans[i].fst,ans[i].sc);
        }
        return 0;
    }
    
    /*
    
     */
  • 相关阅读:
    日期 根据所选日期 获取 之后N天的日期
    错误退出登录
    挂载路由导航守卫 router
    缓存 ssessionStorage&localStorage
    vue项目 第三方图标库阿里图库
    码云新建仓库 以及本地上传
    sql的四种连接-左外连接、右外连接、内连接、全连接
    C#中常用修饰符
    接口的隐式和显式实现
    C#break、continue、return、goto
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10167285.html
Copyright © 2011-2022 走看看