解法
DFS。途中で1000000とかセグフォで逝っちゃうんじゃね?って思いながら組んでいったが、
案の定逝ってしまったのでBFSに書き直して勝ったと思っていたら負けていた。
素数配列の大きさが100001で一桁足りないじゃんって気付くまで時間がかかった。
洞穴のマップを最初に最大値まで求めて作っておく。あと素数も。
これはdy[],dx[]のアレを考慮してやって、進行方向の左側に数字が入ってなかったら曲がろうという方針。
某副部長兼キチガイが提案してくれたので頭いいなと思った。この実装はすぐできた。
ちゃんと答えまで出たらmax_costをint型からpairにして最後に通った素数の判定を感で付け加えた。
ソース
#include<iostream> #include<vector> #include<queue> #include<algorithm> #include<map> #include<cmath> using namespace std; #define fr first #define sc second const int dy[] = { 0, -1, 0, 1}, dx[] = { 1, 0, -1, 0}; //右上左下 typedef pair< int , int > Pt; int m,n,mas[1005][1005],hw = 1000; Pt buff[1000001],max_cost[1005][1005]; bool prime[1000001]; void Prime_set(){ prime[1] = true; for(int i = 2 ; i * i < 1000001 ; i++ ){ if(!prime[i]) for(int j = i + i ; j < 1000001 ; j += i ) prime[j] = true; } } bool isover(int y,int x){ return x < 0 || !mas[y][x] || mas[y][x] > m; } void make_map(){ fill_n(*mas,1005*1005,0); int cnt = 1,muki = 3; Pt now = Pt( hw / 2, hw / 2),St; while(cnt <= 1000000){ buff[cnt] = Pt(now.fr,now.sc); mas[now.fr][now.sc] = cnt++; Pt magaru = Pt( now.fr + dy[(muki + 1) % 4], now.sc + dx[(muki + 1) % 4]); if(!mas[magaru.fr][magaru.sc]) muki = (muki + 1) % 4, now = magaru; else now.fr += dy[muki], now.sc += dx[muki]; } } Pt dfs(Pt now){ if(max_cost[now.fr][now.sc] != Pt(-1,-1)) return max_cost[now.fr][now.sc]; Pt ret = Pt(); for(int i = 0 ; i < 3 ; i++ ){ int nx = now.sc + dx[i]; if(!isover(now.fr+1,nx)) ret = max(ret,dfs(Pt(now.fr+1,nx))); } if(!ret.sc && !prime[mas[now.fr][now.sc]]) ret.sc = mas[now.fr][now.sc]; return max_cost[now.fr][now.sc] = Pt(ret.fr+!prime[mas[now.fr][now.sc]],ret.sc); } int main(){ Prime_set(); make_map(); while(cin >> m >> n , m){ fill_n(*max_cost,1005*1005,Pt(-1,-1)); Pt ans = dfs(buff[n]); cout << ans.fr << " " << ans.sc << endl; } }
0 件のコメント:
コメントを投稿