1
#include<stdio.h>
#include<math.h>
struct line
{
double x1,y1,x2,y2;
};
struct point
{
double x,y;
};
const double delta=1e-6;
bool ok;
int T,n,m,i,j,k;
double scale;
point pL,pS;
line tL;
line L[60],S[60],SN[60];
line in()
{
double tmp;
line t;
scanf("%lf %lf %lf %lf",&t.x1,&t.y1,&t.x2,&t.y2);
if(t.x1>t.x2+delta)
{
tmp=t.x1;
t.x1=t.x2;
t.x2=tmp;
}
if(t.y1>t.y2+delta)
{
tmp=t.y1;
t.y1=t.y2;
t.y2=tmp;
}
return t;
}
bool same(double x,double y)
{
return (y-delta<x && x<y+delta);
}
bool findS(line p)
{
int i;
for(i=0;i<n;i++)
{
if(same(p.x1,p.x2)&&same(L[i].x1,L[i].x2)&&same(p.x1,L[i].x1))
if(L[i].y1<=p.y1&&p.y2<=L[i].y2)
return true;
if(same(p.y1,p.y2)&&same(L[i].y1,L[i].y2)&&same(p.y1,L[i].y1))
if(L[i].x1<=p.x1&&p.x2<=L[i].x2)
return true;
}
return false;
}
bool findL(line p)
{
int i;
for(i=0;i<m;i++)
{
if(same(p.x1,p.x2)&&same(SN[i].x1,SN[i].x2)&&same(p.x1,SN[i].x1))
if(SN[i].y1<=p.y1 && p.y2<=SN[i].y2)
return true;
if(same(p.y1,p.y2)&&same(SN[i].y1,SN[i].y2)&&same(p.y1,SN[i].y1))
if(SN[i].x1<=p.x1&&p.x2<=SN[i].x2)
return true;
}
return false;
}
double dis(double x,double y)
{
return sqrt(x*x+y*y);
}
bool check()
{
double MaxX,MaxY,MinX,MinY;
int i,j,k;
MaxX=MinX=pL.x;
MaxY=MinY=pL.y;
for(i=0;i<m;i++)
{
SN[i].x1=(S[i].x1-pS.x)*scale + pL.x;
SN[i].y1=(S[i].y1-pS.y)*scale + pL.y;
SN[i].x2=(S[i].x2-pS.x)*scale + pL.x;
SN[i].y2=(S[i].y2-pS.y)*scale + pL.y;
if(!findS(SN[i]))
return false;
if(SN[i].x1<MinX)
MinX=SN[i].x1;
if(SN[i].x2>MaxX)
MaxX=SN[i].x2;
if(SN[i].y1<MinY)
MinY=SN[i].y1;
if(SN[i].y2>MaxY)
MaxY=SN[i].y2;
}
for(i=0;i<n;i++)
{
if(same(L[i].x1,L[i].x2))
{
if(L[i].x1>MaxX)
{
if(L[i].y1>MaxY)
{
if(dis(L[i].x1-MaxX,L[i].y1-MaxY)<0.005)
return false;
}
else if( L[i].y2<MinY)
{
if(dis(L[i].x1-MaxX,L[i].y2-MinY)<0.005)
return false;
}
else if(L[i].x1-MaxX<0.005)
return false;
}
else if(L[i].x2<MinX)
{
if(L[i].y1>MaxY)
{
if(dis(L[i].x2-MinX,L[i].y1-MaxY)<0.005)
return false;
}
else if(L[i].y2<MinY)
{
if(dis(L[i].x2-MinX,L[i].y2-MinY)<0.005)
return false;
}
else if(MinX-L[i].x2<0.005)
return false;
}
else
{
if(L[i].y2<MinY-0.005 || L[i].y1>MaxY + 0.005)
continue;
if(L[i].y2<MinY || L[i].y1>MaxY)
return false;
tL=L[i];
if(tL.y1<MinY)
tL.y1=MinY;
if(tL.y2>MaxY)
tL.y2=MaxY;
if(!findL(tL))
return false;
}
}
else
{
if(L[i].y1>MaxY)
{
if(L[i].x1>MaxX)
{
if(dis(L[i].x1-MaxX,L[i].y1-MaxY)<0.005)
return false;
}
else if(L[i].x2<MinX)
{
if(dis(L[i].x2-MinX,L[i].y1-MaxY)<0.005)
return false;
}
else if(L[i].y1-MaxY<0.005)
return false;
}
else if(L[i].y2<MinY)
{
if(L[i].x1>MaxX)
{
if(dis(L[i].x1-MaxX,L[i].y2-MinY)<0.005)
return false;
}
else if(L[i].x2<MinX)
{
if(dis(L[i].x2-MinX,L[i].y2-MinY)<0.005)
return false;
}
else if(MinY-L[i].y2<0.005)
return false;
}
else
{
if(L[i].x2<MinX-0.005||L[i].x1>MaxX+0.005)
continue;
if(L[i].x2<MinX || L[i].x1>MaxX)
return false;
tL=L[i];
if(tL.x1<MinX)
tL.x1=MinX;
if(tL.x2<MaxX)
tL.x2=MaxX;
if(!findL(tL))
return false;
}
}
}
return true;
}
void work()
{
int k;
if(m==1)
{
scale=0.005/(S[0].x2-S[0].x1+S[0].y2-S[0].y1);
ok=scale<=1 && check();
}
else for(k=0;k<n;k++)
if((L[k].x1-L[k].x2)*(S[1].x1-S[1].x2) || (L[k].y1-L[k].y2)*(S[1].y1-S[1].y2))
{
if(S[1].x1!=S[1].x2)
{
if(same(S[1].y1,pS.y))
{
if(!same(S[1].x1,pS.x))
scale=(L[k].x1-pL.x)/(S[1].x1-pS.x);
else
scale=(pL.x-L[k].x2)/(pS.x-S[1].x2);
}
else
scale=(L[k].y1-pL.y)/(S[1].y1-pS.y);
}
else
{
if(same(S[1].x1,pS.x))
{
if(!same(S[1].y1,pS.y))
scale=(L[k].y1-pL.y)/(S[1].y1-pS.y);
else
scale=(pL.y-L[k].y2)/(pS.y-S[1].y2);
}
else
scale=(L[k].x1-pL.x)/(S[1].x1-pS.x);
}
ok=scale<=1&&scale>delta&&check();
if(ok)
return ;
}
}
int main()
{
T=0;
while(scanf("%d %d",&m,&n) && (m||n))
{
for(i=0;i<m;i++)
S[i]=in();
for(i=0;i<n;i++)
L[i]=in();
ok=false;
for(i=0;i<n;i++)
for(j=0;j<m;j++) if(!ok)
{
tL=S[0];
S[0]=S[j];
S[j]=tL;
pL.x=L[i].x1;
pL.y=L[i].y1;
pS.x=S[0].x1;
pS.y=S[0].y1;
work();
if(ok)
break;
pL.x=L[i].x2;
pL.y=L[i].y2;
pS.x=S[0].x2;
pS.y=S[0].y2;
work();
if(ok)
break;
}
if(ok)
printf("Case %d: valid puzzle\n\n",++T);
else
printf("Case %d: impossible\n\n",++T);
}
return 0;
}
2
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
struct coor
{
double x,y;
};
const int MaxB=50;
const int MaxC=50;
const int MaxS=50*50;
int B,C,R,Q,i,j,k,cases;
coor BTS[MaxB],city[MaxC];
int S[MaxC][MaxC];
double dis(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
int area(double x,double y)
{
int i,k;
k=0;
double min,tmp;
min=dis(x,y,BTS[0].x,BTS[0].y);
for(i=1;i<B;i++)
{
tmp=dis(x,y,BTS[i].x,BTS[i].y);
if(tmp<min)
{
min=tmp;
k=i;
}
}
return k;
}
int get_switch(double x1,double y1,double x2,double y2)
{
if(area(x1,y1)==area(x2,y2))
return 0;
if(dis(x1,y1,x2,y2)<1e-6)
return 1;
return get_switch(x1,y1,(x1+x2)/2,(y1+y2)/2)+get_switch((x1+x2)/2,(y1+y2)/2,x2,y2);
}
bool init()
{
scanf("%d %d %d %d",&B,&C,&R,&Q);
if(B==0&&C==0&&R==0&&Q==0)
return false;
for(i=0;i<B;i++)
scanf("%lf %lf",&BTS[i].x,&BTS[i].y);
for(i=0;i<C;i++)
scanf("%lf %lf",&city[i].x,&city[i].y);
memset(S,0,sizeof(S));
for(i=0;i<R;i++)
{
scanf("%d %d",&j,&k);
j--;k--;
S[j][k]=S[k][j]=1;
}
for(i=0;i<C;i++)
for(j=i+1;j<C;j++)
{
if(S[i][j]==0)
S[i][j]=MaxS;
else
S[i][j]=get_switch(city[i].x,city[i].y,city[j].x,city[j].y);
S[j][i]=S[i][j];
}
for(i=0;i<C;i++)
S[i][i]=0;
return true;
}
int main()
{
cases=0;
while(init())
{
printf("Case %d:\n",++cases);
for(k=0;k<C;k++)
for(i=0;i<C;i++)
for(j=0;j<C;j++)
if(S[i][j]>S[i][k]+S[k][j])
S[i][j]=S[i][k]+S[k][j];
for(i=0;i<Q;i++)
{
scanf("%d %d",&j,&k);
j--;k--;
if(S[j][k]>=MaxS)
printf("Impossible\n");
else
printf("%d\n",S[j][k]);
}
}
return 0;
}
3
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int MaxC=20;
const int MaxJ=10;
int cases,NC,NJ,T,DC,map,best_map,ans,i,k;
int road[MaxC][MaxC],judges[MaxJ],fa[MaxC];
bool init()
{
int NR,i,C1,C2;
scanf("%d",&NC);
if(NC==-1)
return false;
scanf("%d",&DC);
DC--;
T=1<<DC;
scanf("%d",&NR);
memset(road,0,sizeof(road));
ans=1000;
for(i=0;i<NR;i++)
{
scanf("%d %d",&C1,&C2);
C1--;C2--;
scanf("%d",&road[C1][C2]);
road[C2][C1]=road[C1][C2];
ans+=road[C1][C2];
}
scanf("%d",&NJ);
for(i=0;i<NJ;i++)
{
scanf("%d",&judges[i]);
judges[i]--;
T+=1<<judges[i];
}
return true;
}
void check(int map)
{
int i,j,k,sum,min;
int d[MaxC];
for(i=0;i<MaxC;i++)
d[i]=-2;
d[DC]=-1;
for(i=0;i<MaxC;i++)
if(((1<<i)&map)&&road[DC][i])
{
d[i]=road[DC][i];
fa[i]=DC;
}
sum=0;
while(1)
{
min=ans+10;
for(i=0;i<MaxC;i++)
if(d[i]>0&&d[i]<min)
{
min=d[i];
k=i;
}
if(min>ans)
break;
sum+=min;
d[k]=-1;
for(i=0;i<MaxC;i++)
if((1<<i)&map&&road[k][i])
if(d[i]==-2||d[i]>road[k][i])
{
d[i]=road[k][i];
fa[i]=k;
}
}
for(i=0;i<MaxC;i++)
if(((1<<i)&map)&&d[i]==-2)
return;
if(sum<ans)
{
ans=sum;
best_map=map;
}
else if(sum==ans)
{
j=0;k=0;
for(i=0;i<MaxC;i++)
{
if((1<<i)&best_map) j++;
if((1<<i)&map) k++;
}
if(j>k)
{
best_map=map;
return;
}
if(j<k)
return;
for(i=0;i<MaxC;i++)
{
if(((1<<i)&best_map)&&!((1<<i)&map))
return;
if(!((1<<i)&best_map)&&((1<<i)&map))
{
best_map=map;
return;
}
}
}
}
int main()
{
cases=0;
while(init())
{
best_map=0;
for(map=0;map<(1<<NC);map++)
if((map&T)==T)
check(map);
printf("Case %d: distance = %d\n",++cases,ans);
check(best_map);
for(i=0;i<NJ;i++)
{
printf(" %d",judges[i]+1);
k=judges[i];
while(k!=DC)
{
printf("-%d",fa[k]+1);
k=fa[k];
}
printf("\n");
}
printf("\n");
}
return 0;
}