Gym 101667F Philosopher's Walk 深搜+思維
阿新 • • 發佈:2018-12-17
題意:
給你一個最原始的2*2的格子以及行走路線,之後每一個圖都由上一個圖組成,具體為:假設上一個圖為f(n-1),那麼新的圖的左下角為f(n-1)順時針旋轉90°,左上和右上就是f(n-1),右下角為f(n-1)逆時針旋轉90°。新拼接的圖可以只需連線一條線即可,每次都從左下角開始走起,給你一個步數,問這一步的時候所在的座標位置。
做法:
畫一個轉移狀態的圖,每一個大狀態又可以得到下一個小狀態,每個小狀態的座標增加情況都不一樣,只要一個深搜就可以了。附上一個轉移圖。(表示,深搜真菜。。)
程式碼如下:
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll n,k,ansx,ansy; void ax(int add){ansx+=add;} void ay(int add){ansy+=add;} int changedir(int now,int next,int add){ if(now==1) { if(next==1) {return 2;} else if(next==2) {ay(add);return 1;} else if(next==3) {ax(add),ay(add);return 1;} else {ax(add);return 3;} } else if(now==2){ if(next==1) {return 1;} else if(next==2) {ax(add);return 2;} else if(next==3) {ax(add),ay(add);return 2;} else {ay(add);return 4;} } else if(now==3){ if(next==1) {ax(add),ay(add);return 4;} else if(next==2) {ay(add);return 3;} else if(next==3) {return 3;} else {ax(add);return 1;} } else { if(next==1) {ax(add),ay(add);return 3;} else if(next==2) {ax(add);return 4;} else if(next==3) {return 4;} else {ay(add);return 2;} } } void dfs(int bianchang,int now,int k,int dir){//1為正,2為右 3為左 4為下 int kuai=now/4; if(k<=kuai){ if(kuai==1){ changedir(dir,1,bianchang/2); return ; } dfs(bianchang/2,kuai,k,changedir(dir,1,bianchang/2)); } else if(k<=2*kuai){ if(kuai==1){ changedir(dir,2,bianchang/2); return ; } dfs(bianchang/2,kuai,k-kuai,changedir(dir,2,bianchang/2)); } else if(k<=3*kuai){ if(kuai==1){ changedir(dir,3,bianchang/2); return ; } dfs(bianchang/2,kuai,k-2*kuai,changedir(dir,3,bianchang/2)); } else { if(kuai==1){ changedir(dir,4,bianchang/2); return ; } dfs(bianchang/2,kuai,k-3*kuai,changedir(dir,4,bianchang/2)); } } int main(){ ansx=0,ansy=0; scanf("%lld%lld",&n,&k); ll now=1,tmp=n; while(tmp!=1){ now*=4; tmp/=2; } dfs(n,now,k,1); printf("%lld %lld\n",ansx+1,ansy+1); return 0; }