标签:eof int pair UNC 方案 path mat roo eps
题意:
网格图选中三个格,让你选中一些格子把这三个格子连起来,使得选中的格子总数最小。最后输出方案
网格范围为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; } /* */
Codeforces 1087C Connect Three (思维+模拟)
标签:eof int pair UNC 方案 path mat roo eps
原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10167285.html