poj 2296 (2 - SAT + 2 점)
이 문 제 는 두 가지 그림 을 만 드 는 방식 이 있다.
1. 네 가지 상황 으로 나 뉜 다.i 위로, j 위로, 두 정사각형 이 교차 하 는 지 여 부 를 판단 하고 교차 하면 건축 변 i - > j ', j - > i';
i 위로, j 아래로, 두 정사각형 이 교차 하 는 지 여 부 를 판단 합 니 다. 만약 에 교차 하면 건축 변 i - > j, j - > i ';
i 아래로, j 위로, 두 정사각형 이 교차 하 는 지 여 부 를 판단 합 니 다. 만약 에 교차 하면 건축 변 i '- > j', j - > i;
i 아래로, j 아래로, 두 정사각형 이 교차 하 는 지 여 부 를 판단 하고, 교차 하면 변경 i '- > j, j' - > i;
2. 두 정사각형 이 어떻게 서로 교차 하지 않 는 지 직접 판단 하지만 이렇게 하면 넣 어야 할 변 을 빠 뜨리 기 쉽다. 이 문제 의 i 는 반드시 위로, j 는 반드시 아래로 내 려 가 야 하 는 상황 이다.
가장자리 (i + n, i), (j, j + n) 를 더 해 야 합 니 다. i 는 위로 올 라 가 야 하고 j 는 아래로 내 려 가 야 합 니 다. 추가 하지 않 으 면 wrong 입 니 다.이런 건축 방식 은 그다지 익숙 하지 않다.
#include<stdio.h>
#include<string.h>
#include<stack>
#define N 300
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
struct edge
{
int ed,next;
}E[N*N];
struct op
{
int x,y;
}p[N];
int low[N],dfs[N],belong[N],ins[N],idx,ans,num,first[N],n;
void addedge(int x,int y)
{
E[num].ed=y;
E[num].next=first[x];
first[x]=num++;
}
int cmp(const void *a,const void *b)
{
struct op *c,*d;
c=(struct op *)a;
d=(struct op *)b;
return d->y-c->y;
}
void insit()
{
memset(low,0,sizeof(low));
memset(dfs,-1,sizeof(dfs));
memset(belong,0,sizeof(belong));
memset(ins,0,sizeof(ins));
memset(first,-1,sizeof(first));
idx=ans=num=0;
}
stack<int>Q;
void Tarjan(int x)
{
int v,p;
low[x]=dfs[x]=idx++;
Q.push(x);
ins[x]=1;
for(p=first[x];p!=-1;p=E[p].next)
{
v=E[p].ed;
if(dfs[v]==-1)
{
Tarjan(v);
low[x]=low[x]>low[v]?low[v]:low[x];
}
else if(ins[v]==1)
low[x]=low[x]>dfs[v]?dfs[v]:low[x];
}
if(dfs[x]==low[x])
{
do
{
v=Q.top();
Q.pop();
ins[v]=0;
belong[v]=ans;
}while(v!=x);
ans++;
}
}
bool cross(int mid,int i,int j,int s1,int s2)
{
double x1=p[i].x-mid/2.0,x2=p[i].x+mid/2.0;
double y1=p[i].y,y2=p[i].y+s1*mid;
double x3=p[j].x-mid/2.0,x4=p[j].x+mid/2.0;
double y3=p[j].y,y4=p[j].y+s2*mid;
if(max(x1,x2)<=min(x3,x4))return false;
if(min(x1,x2)>=max(x3,x4))return false;
if(max(y1,y2)<=min(y3,y4))return false;
if(min(y1,y2)>=max(y3,y4))return false;
return true;
}
int judge(int d)
{
int i,j;
insit();
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
//*********************************************************************************
/*
if(abs(p[i].x-p[j].x)>=d)continue;// d,
if(p[i].y-p[j].y>=2*d)continue;// 2d,
if(p[i].y-p[j].y<d)// d,
{
if(p[i].y==p[j].y)
{
addedge(i,j+n);//i ,j
addedge(j,i+n);//j ,i
addedge(i+n,j);
addedge(j+n,i);
}
else
{
addedge(i,j+n);//i ,j (i j )
addedge(i+n,i);//i
addedge(j,j+n);//j
addedge(j+n,i);//(j' i' )
}
}
else if(p[i].y-p[j].y<2*d)
{
addedge(i+n,j+n);//
addedge(j,i);//
}
*/
//*********************************************************************************
if(cross(d,i,j,1,1))//1 ,-1
{
addedge(i,j+n);
addedge(j,i+n);
}
if(cross(d,i,j,1,-1))
{
addedge(i,j);
addedge(j+n,i+n);
}
if(cross(d,i,j,-1,1))
{
addedge(i+n,j+n);
addedge(j,i);
}
if(cross(d,i,j,-1,-1))
{
addedge(i+n,j);
addedge(j+n,i);
}
}
for(i=0;i<n*2;i++)
if(dfs[i]==-1)
Tarjan(i);
for(i=0;i<n;i++)
if(belong[i]==belong[i+n])
return 0;
return 1;
}
int main()
{
int i,t,min,max,mid,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
qsort(p,n,sizeof(p[0]),cmp);
min=0;max=20000;
sum=0;
while(min<=max)
{
mid=(min+max)/2;
if(judge(mid))
{
sum=mid;
min=mid+1;
}
else max=mid-1;
}
printf("%d
",sum);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Codility Lesson3】FrogJmpA small frog wants to get to the other side of the road. The frog is currently located at position X and wants to get to...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.