Description
Input
Output
Sample Input
1 6 1 1 2 3 3 2 4 4 10 4 2 5
Sample Output
2
思路:判断相交可以,找出两个正方形的中心点判断,这样高端大气,不用分类讨论。
#include<cstdio> #include<cstring> #include<iostream> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof(f)) using namespace std; const int mm=1410; const int oo=2e4+9; const double eps=1e-6; class Edge { public:int v,next; }; class cicle { public:int x,y; }f[mm]; int n; class TWO_SAT { public: int dfn[mm],e_to[mm],stack[mm]; Edge e[mm*mm*2]; int edge,head[mm],top,dfs_clock,bcc; void clear() { edge=0;clr(head,-1); } void add(int u,int v) { e[edge].v=v;e[edge].next=head[u];head[u]=edge++; } void add_my(int x,int xval,int y,int yval) { x=x+x+xval;y=y+y+yval; add(x,y); } void add_clause(int x,int xval,int y,int yval) {///x or y x=x+x+xval; y=y+y+yval; add(x^1,y);add(y^1,x); } void add_con(int x,int xval)//x is xval { x=x+x+xval; add(x^1,x); } int tarjan(int u) { int lowu,lowv; lowu=dfn[u]=++dfs_clock; int v; stack[top++]=u; for(int i=head[u];~i;i=e[i].next) { v=e[i].v; if(!dfn[v]) { lowv=tarjan(v); lowu=min(lowv,lowu); } else if(e_to[v]==-1)//in stack lowu=min(lowu,dfn[v]); } if(dfn[u]==lowu) { ++bcc; do{ v=stack[--top]; e_to[v]=bcc; }while(v!=u); } return lowu; } bool find_bcc(int n) { clr(e_to,-1); clr(dfn,0); bcc=dfs_clock=top=0; FOR(i,0,2*n-1) if(!dfn[i]) tarjan(i); for(int i=0;i<2*n;i+=2) if(e_to[i]==e_to[i^1])return 0; return 1; } bool build(int x) { clear(); FOR(i,1,n) FOR(j,i+1,n) FOR(k,0,1)FOR(l,0,1) if(intersex(i,k,j,l,x)) { //printf("%d %d %d %d %d\n",i,k,j,l,x); add_clause(i-1,k^1,j-1,l^1); } return find_bcc(n*2); } bool intersex(int i,int a,int j,int b,int mid) { float x,y,xx,yy,dis=mid; x=f[i].x;xx=f[j].x; if(a) { y=f[i].y+dis/2; } else y=f[i].y-dis/2; if(b) { yy=f[j].y+dis/2; } else yy=f[j].y-dis/2; if(x<xx)swap(x,xx); if(y<yy)swap(y,yy); //cout<<x<<" "<<xx<<" "<<mid<<endl; // printf("%d %d %d %d %d\n",x,xx,y,yy,mid); if(x-xx>=dis||y-yy>=dis)return 0; else return 1; } }two; char s[44]; int main() { int a,b,c,d,cas; while(~scanf("%d",&cas)) while(cas--) { scanf("%d",&n); FOR(i,1,n) { scanf("%d%d",&f[i].x,&f[i].y); } int l=0,r=oo,mid,ans=0; while(l<=r) { mid=(l+r)/2; if(two.build(mid)) l=mid+1,ans=mid; else r=mid-1; } //cout<<(l+r)/2<<endl; printf("%d\n",ans); } return 0; }