2006年国内予選C問題(Hexerpents of Hexwamp)(2007/07/25(水) 01:04:31)
2006年ICPC国内予選のC問題を暇なので解いてみた!
後から思ったんやけど、幅優先の方がいいね・・・
実際にコレ実行したら結構時間かかるし(汗
でも、絶対にどこか枝刈りで切るはずだ!!
本日のコーディングミス
こんな酷いミス久しぶりww
何回か、コード見直したのに全く気づかなかった
bool isHit(int x, int y){ for(int i = 0; i < node.size(); i++){ if(x == node[0].x && y == node[0].y){ return true; } } for(int i = 0; i < block.size(); i++){ if(x == block[0].x && y == block[0].y){ return true; } } return false; }
ソース
#include <iostream> #include <map> #include <vector> using namespace std; typedef struct Point{ int x, y; bool operator == (const Point p) const{ return x == p.x && y == p.y; } bool operator < (const Point p) const{ return x < p.x || x == p.x && y < p.y; } }Point; int n, k; vector<Point> node; vector<Point> block; Point goal; map<vector<Point>, map<int, int> > hash; int vect[6][2] = {{0, -1}, {1, -1}, {1, 0}, {0, 1}, {-1, 1}, {-1, 0}}; bool isNext(int x1, int y1, int x2, int y2); bool isHit(int x, int y); bool isMove(int index, int v); int solv(int step); int solv2(int step, int i); bool isNext(int x1, int y1, int x2, int y2){ for(int i = 0; i < 6; i++){ if(x1 - x2 == vect[i][0] && y1 - y2 == vect[i][1]){ return true; } } return false; } bool isHit(int x, int y){ for(int i = 0; i < node.size(); i++){ if(x == node[i].x && y == node[i].y){ return true; } } for(int i = 0; i < block.size(); i++){ if(x == block[i].x && y == block[i].y){ return true; } } return false; } bool isMove(int index, int v){ Point np = {node[index].x + vect[v][0], node[index].y + vect[v][1]}; if(isHit(np.x, np.y)){ return false; } //after node if(index != 0){ if(!isNext(np.x, np.y, node[index - 1].x, node[index - 1].y)){ return false; } } //before node if(index != node.size() - 1){ if(!isNext(np.x, np.y, node[index + 1].x, node[index + 1].y)){ return false; } } return true; } bool checkNode(){ for(int i = 0; i < node.size() - 1; i++){ for(int j = i + 2; j < node.size(); j++){ if(isNext(node[i].x, node[i].y, node[j].x, node[j].y))return false; } } return true; } int solv(int step){ if(step >= 20)return 20; if(node[0] == goal)return step; int c = hash[node][step]; if(c > 0)return c; int s = solv2(step, 0); hash[node][step] = s; return s; } int solv2(int step, int i){ if(i >= node.size()){ if(checkNode())return solv(step + 1); return 20; } //no move int min = solv2(step, i + 1); //move for(int j = 0; j < 6; j++){ //node move check if(isMove(i, j)){ node[i].x += vect[j][0]; node[i].y += vect[j][1]; int s = solv2(step, i + 2);//move next next node if(min > s)min = s; node[i].x -= vect[j][0]; node[i].y -= vect[j][1]; } } return min; } int main(){ while(cin >> n, (n)){ node.clear(); for(int i = 0; i < n; i++){ Point tmp; cin >> tmp.x >> tmp.y; node.push_back(tmp); } cin >> k; block.clear(); for(int i = 0; i < k; i++){ Point tmp; cin >> tmp.x >> tmp.y; block.push_back(tmp); } hash.clear(); cin >> goal.x >> goal.y; cout << solv(0) << endl; } return 0; }