AOJ 2008 Dragon Fantasy
問題
解法
全探索+枝刈り。BFSでときました。枝刈りをするときはループに入らせる前に走査して枝刈りさせないと無駄な探索が入り込んだりすることを知った。
心臓に悪いコード
int n; int hx, hy, dx, dy, cx[21], cy[21]; double dist(double ax, double ay, double bx, double by){ return sqrt((ax-bx)*(ax-bx) + (ay-by)*(ay-by)); } int dfs(int c, double t, int x, int y, int *used){ if(c == n) return 1; rep(i, n){ if(used[i]) continue; if(t + dist(x, y, cx[i], cy[i]) + EPS > dist(dx, dy, cx[i], cy[i])) return 0; } rep(i, n){ if(used[i]) continue; double nt = dist(x, y, cx[i], cy[i]); cy[i]); cy[i])); if(t + nt + EPS > dist(dx, dy, cx[i], cy[i])) return 0; used[i] = 1; if(dfs(c+1, t + nt, cx[i], cy[i], used)) return 1; used[i] = 0; } return 0; } int main(){ while(scanf("%d%d%d%d%d", &n, &hx, &hy, &dx, &dy) && n+hx+hy+dx+dy){ rep(i, n) scanf("%d%d", cx+i, cy+i);; int used[21]; memset(used, 0, sizeof(used)); if(dfs(0, 0, hx, hy, used)) puts("YES"); else puts("NO"); } return 0; }