2011 ACM-ICPC Asia Hsinchu Regional Contest
一共会有八个方向,查询八个方向的向量没个向量需要多少个。然后存到 path[] 里。
在查找到一条完整的 path 后,就开始进行判断。对八个方向注意判断。
正确的解法是:暴力一遍(256次)查询应该按照什么顺序查询比较转头的次数最少。
错误的解法是:贪心,按照方向从向上的方向开始顺时针查询一次,逆时针查询一次,去最小。(有反例。方向分别是0,1,2,6 7。最简单的不是0 1 2 6 7 而是0 1 2 7 6)。但是数据很水,居然水过了。请勿模仿。
把错误的代码贴上来。在 check 里,查询 j 的时候,改成 dfs 暴力就好。
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
const double EPS=1e-8;
const int MAXN=20;
const int INF=1<<30;
struct Pointt{
double x,y;
}p[MAXN];
Pointt apnt,bpnt;
double ma=50.0*sqrt(2.0);
const double dx[]={0.0,ma,100.0,ma,0.0,-ma,-100.0,-ma};
const double dy[]={100.0,ma,0.0,-ma,-100.0,-ma,0.0,ma};
int n,ans,path[10],mar[10];
int check(){
int ans2=INF;
int ans3;
Pointt all;
all.x=0.0;
all.y=0.0;
int last=0;
memset(mar,0,sizeof(mar));
// all.x+=dx[0]*path[0];
//all.y+=dy[0]*path[0];
// mar[0]=1;
ans3=0;
int min1;
int min2;
int now;
int counttt=0;
for(int i=0;i<8;i++){
if(path[i]!=0){
//printf("path i %d %d\n",i,path[i]);
counttt++;
}
}
//printf("%d\n",counttt);
// counttt--;
for(int i=0;i<counttt;i++){
min2=INF;
for(int j=0;j<8;j++){
if(path[j]!=0&&mar[j]==0){
min1=min(fabs(j-last),fabs(8-(j-last)));
if(min2>min1){
now=j;
min2=min1;
// printf("j %d\n",j);
}
}
}
// printf("now %d\n",now);
mar[now]=1;
all.x+=dx[now]*path[now];
all.y+=dy[now]*path[now];
//printf("~~%.lf %.lf\n",all.x,all.y);
last=now;
ans3+=min2;
// printf("ans3 %d\n",ans3);
}
if(all.x+EPS>apnt.x && all.x<bpnt.x+EPS && all.y+EPS>apnt.y && all.y<bpnt.y+EPS){
ans2=min(ans3,ans2);
//printf("ans2 %d\n",ans2);
}
all.x=0.0;
all.y=0.0;
last=0;
// all.x+=dx[0]*path[0];
// all.y+=dy[0]*path[0];
memset(mar,0,sizeof(mar));
// mar[0]=1;
ans3=0;
// min1=INF;
//min2=INF;
for(int i=0;i<counttt;i++){
min2=INF;
for(int j=0;j<8;j++){
if(path[j]!=0&&mar[j]==0){
min1=min(fabs(j-last),fabs(8-(j-last)));
if(min2>min1){
now=j;
min2=min1;
// printf("j %d\n",j);
}
}
}
// printf("now %d\n",now);
mar[now]=1;
all.x+=dx[now]*path[now];
all.y+=dy[now]*path[now];
//printf("~~%.lf %.lf\n",all.x,all.y);
last=now;
ans3+=min2;
// printf("ans3 %d\n",ans3);
}
if(all.x+EPS>apnt.x && all.x<bpnt.x+EPS && all.y+EPS>apnt.y && all.y<bpnt.y+EPS){
ans2=min(ans3,ans2);
//printf("ans2 %d\n",ans2);
}
return ans2;
}
void dfs(int pp,int qq){
if(pp==7){
path[7]=qq;
int count=check();
// printf("ans2 %d\n",count);
ans=min(count,ans);
return ;
}
for(int i=0;i<=qq;i++){
path[pp]=i;
dfs(pp+1,qq-i);
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
scanf("%lf%lf",&apnt.x,&apnt.y);
scanf("%lf%lf",&bpnt.x,&bpnt.y);
apnt.x+=10.0;
apnt.y+=10.0;
bpnt.x-=10.0;
bpnt.y-=10.0;
ans=INF;
memset(path,0,sizeof(path));
dfs(0,n);
if(ans<INF){
printf("%d\n",ans);
}
else
printf("-1\n");
}
return 0;
}