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\nb:%d %d\n",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\n",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\n",i,a[i].fst,a[i].sc);
    }
    //printf("%d %d %d %d\n",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\n",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\n",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\n",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\n",pos.fst,pos.sc);
    //printf("  %d\n",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\n",ans.size());
    sort(ans.begin(), ans.end(), cmp);
    for(int i = 0; i < (int)ans.size(); i++){
        printf("%d %d\n",ans[i].fst,ans[i].sc);
    }
    return 0;
}

/*

 */

 

posted @ 2018-12-24 10:34  wrjlinkkkkkk  阅读(490)  评论(0编辑  收藏  举报