应该说到目前为止这道题我还没有解决,纠结了很长时间。
感觉这道题如果用dfs的话,对于输入的处理是需要“运气”的,也就是排序时的依据是a.x*a.w<b.x*b.w还是a.counter1<b.counter1可能会对运行时间存在较大影响,应该是测试数据中存在特殊数据使得运行时间很长。下面的代码在zoj上可以0msAC,但在poj和uva上一个tle一个wa。我又使用了不“正当”的技巧tick。。总之这道题先放这里,等我掌握了dp再来一试。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,a1,a2,a3,ok,visleft[20],visright[20],tick;
double l,w,lcounter1,lcounter2,lclockwise1,lclockwise2;
double ans[20][2];
struct node
{
double x,w,counter1,counter2,clockwise1,clockwise2;
}right[20],left[20],mid[20];
int cmp1(node a,node b)
{
return -a.x*a.w<-b.x*b.w;
}
int cmp2(node a,node b)
{
return a.x*a.w<b.x*b.w;
}
int calcu()
{
//printf("test");
double a,b;
int i;
a=lcounter1,b=lclockwise1;
for(i=0;i<a3;i++)
b+=mid[i].clockwise1;
for(i=0;i<a1;i++)
{
if(visleft[i]==1)
a+=left[i].counter1;
}
for(i=0;i<a2;i++)
{
if(visright[i]==1)
b+=right[i].clockwise1;
}
//printf("%lf %lf\n",a,b);
if(a>b)
return 0;
a=lcounter2,b=lclockwise2;
for(i=0;i<a3;i++)
a+=mid[i].counter2;
for(i=0;i<a1;i++)
{
if(visleft[i]==1)
a+=left[i].counter2;
}
for(i=0;i<a2;i++)
{
if(visright[i]==1)
b+=right[i].clockwise2;
}
if(a<b)
return 0;
return 1;
}
void dfs(int all,int which)
{
tick++;
if(tick>50000)
return ;
if(ok==1)
return;
int i,j;
if(all==n)
{
ok=1;
/*for(i=0;i<a1;i++)
{
//printf("%d\n",visleft[i]);
if(visleft[i]==0)
{
//printf("a1\n");
ans[n-1][0]=left[i].x;
ans[n-1][1]=left[i].w;
}
}
for(i=0;i<a2;i++)
{
//printf("%d\n",visright[i]);
if(visright[i]==0)
{
//printf("a2\n");
ans[n-1][0]=right[i].x;
ans[n-1][1]=right[i].w;
}
}*/
return ;
}
if(which==0)
{
//printf("test%d",all);
for(i=0;i<a1;i++)
{
if(visleft[i]==0)
{
//printf("test%d",all);
visleft[i]=1;
if(calcu())
{
//printf("test%d",all);
//printf("%d %lf %lf\n",all,left[i].x,left[i].w);
ans[all][0]=left[i].x;
ans[all][1]=left[i].w;
dfs(all+1,0);
if(ok==1)
return ;
visleft[i]=0;
}
else
{
visleft[i]=0;
break;
}
}
}
for(i=0;i<a2;i++)
{
if(visright[i]==0)
{
visright[i]=1;
if(calcu())
{
ans[all][0]=right[i].x;
ans[all][1]=right[i].w;
dfs(all+1,1);
if(ok==1)
return ;
visright[i]=0;
}
else
{
visright[i]=0;
break;
}
}
}
}
else if(which==1)
{
for(i=0;i<a2;i++)
{
if(visright[i]==0)
{
visright[i]=1;
if(calcu())
{
ans[all][0]=right[i].x;
ans[all][1]=right[i].w;
dfs(all+1,1);
if(ok==1)
return ;
visright[i]=0;
}
else
{
visright[i]=0;
break;
}
}
}
for(i=0;i<a1;i++)
{
if(visleft[i]==0)
{
visleft[i]=1;
if(calcu())
{
ans[all][0]=left[i].x;
ans[all][1]=left[i].w;
dfs(all+1,0);
if(ok==1)
return ;
visleft[i]=0;
}
else
{
visleft[i]=0;
break;
}
}
}
}
//printf("test%d",all);
}
int main()
{
int count=1,i,j,all;
double a,b,help;
while(scanf("%lf %lf %d",&l,&w,&n)&&n!=0)
{
a1=a2=a3=all=ok=tick=0;
memset(visleft,0,80);
memset(visright,0,80);
lcounter1=lclockwise2=(l-3)*(l-3)/8/l*w;
lcounter2=lclockwise1=(l+3)*(l+3)/8/l*w;
for(i=0;i<n;i++)
{
scanf("%lf %lf",&a,&b);
if(a>=-1.5&&a<=1.5)
{
mid[a3].x=a;
mid[a3].clockwise1=(a+1.5)*b;
//printf("%lf\n",(a+1.5)*b);
mid[a3].clockwise2=0;
mid[a3].counter1=0;
mid[a3].counter2=(1.5-a)*b;
//printf("%lf\n",(1.5-a)*b);
mid[a3++].w=b;
}
else if(a<-1.5)
{
left[a1].x=a;
left[a1].w=b;
left[a1].counter1=-b*(a+1.5);
//printf("%lf\n",-b*(a+1.5));
left[a1++].counter2=-b*(a-1.5);
//printf("%lf\n",-b*(a-1.5));
}
else if(a>1.5)
{
right[a2].x=a;
right[a2].w=b;
right[a2].clockwise1=b*(a+1.5);
//printf("%lf\n",b*(a+1.5));
right[a2++].clockwise2=b*(a-1.5);
//printf("%lf\n",b*(a-1.5));
}
}
sort(left,left+a1,cmp1);
sort(right,right+a2,cmp2);
//for(i=0;i<a1;i++)
// printf("%lf %lf\n",left[i].x,left[i].w);
//for(i=0;i<a2;i++)
// printf("%lf %lf\n",right[i].x,right[i].w);
for(i=0;i<a3;i++)
{
ans[all][0]=mid[i].x;
ans[all++][1]=mid[i].w;
}
printf("Case %d:\n",count++);
help=0;
for(i=0;i<a3;i++)
{
help+=mid[i].clockwise1;
}
for(i=0;i<a2;i++)
{
help+=right[i].clockwise1;
}
for(i=0;i<a1;i++)
if(left[i].counter1>help)
{
printf("Impossible\n");
goto next;
}
help=0;
for(i=0;i<a3;i++)
{
help+=mid[i].counter2;
}
for(i=0;i<a1;i++)
{
help+=left[i].counter2;
}
for(i=0;i<a1;i++)
if(right[i].clockwise1>help)
{
printf("Impossible\n");
goto next;
}
dfs(a3,0);
if(ok==0)
{
tick=0;
dfs(a3,1);
}
if(ok==0)
printf("Impossible\n");
else
{
for(i=n-1;i>=0;i--)
printf("%.0lf %.0lf\n",ans[i][0],ans[i][1]);
}
next:{}
}
return 0;
}