Codeforces Round #190 Div1A Ciel and Robot
問題
ロボットが最初(0,0)にいて、上下左右にそれぞれ1マスずつ動く命令がUDLRで構成させた命令になります。
命令はstringで与えられ、高々100命令です。
最後の命令まで行ったら最初の命令に戻って延々繰り返します。
(0,0)から命令を無限に実行したとき、(a,b)を通るか判定しなさい。
解法
真面目に考えると場合分けが大変面倒になりそうですが、
命令が高々100なので、大ざっぱなところまで近づいてから十分な回数の個別シミュレーションをしても間に合いそうです。
というわけで、命令ループの終わりまでに(a,b)の100四方くらいまで近づいてきたら、そこから1000回くらい座標移動をシミュレートするという超絶アバウトなプログラムを書いたところ、普通に通りました。
なお割り算に絶対値を取っているので、本来進めないはずの逆側からシミュレーションが始まることもありますが、(a,b)と十分な距離を取っているところからスタートし、ロボはそことは逆側に走っていくので問題ありません。
プログラム
#include<iostream> #include <fstream> #include <stdio.h> #include <stdlib.h> #define _USE_MATH_DEFINES #include <math.h> #include<string> #include<vector> #include<cmath> #include<stack> #include<queue> #include<sstream> #include<algorithm> #include<map> #include<complex> using namespace std; #define li long long int #define rep(i,to) for(int i=0;i<((int)(to));i++) #define repp(i,start,to) for(int i=(int)(start);i<((int)(to));i++) #define pb push_back #define sz(v) ((li)(v).size()) #define bgn(v) ((v).begin()) #define eend(v) ((v).end()) #define allof(v) (v).begin(), (v).end() #define dodp(v,n) memset(v,(li)n,sizeof(v)) #define bit(n) (1ll<<(li)(n)) #define mp(a,b) make_pair(a,b) #define rin rep(i,n) #define EPS 1e-10 #define ETOL 1e-8 #define MOD 1000000007 #define p2(a,b) cout<<a<<"\t"<<b<<endl #define p3(a,b,c) cout<<a<<"\t"<<b<<"\t"<<c<<endl li program[100]; li dx[4]={0,0,-1,1}; li dy[4]={1,-1,0,0}; li a,b,n; bool check(li x, li y, li limStep){ li idx=0; li step=0; if(a==x && b==y)return true; while(step<limStep){ x+=dx[program[idx]]; y+=dy[program[idx]]; if(a==x && b==y)return true; idx=(idx+1)%n; step++; } return false; } int main(){ cin>>a>>b; if(a==0 && b==0){ puts("Yes"); return 0; } string s; cin>>s; n=sz(s); rin{ if(s[i]=='U')program[i]=0; else if(s[i]=='D')program[i]=1; else if(s[i]=='L')program[i]=2; else program[i]=3; } if(max(abs(a),abs(b)) < 100){ if(check(0,0,n*1000))puts("Yes"); else puts("No"); return 0; } li x1=0, y1=0; rin{ x1+=dx[program[i]]; y1+=dy[program[i]]; } li step; if(x1==0 && y1==0){ puts("No"); return 0; } else if(x1==0)step=(abs(b)-100)/y1; else if(y1==0)step=(abs(a)-100)/x1; else step=min((abs(a)-100)/x1,(abs(b)-100)/y1); step=abs(step); if(check(x1*step,y1*step,n*1000))puts("Yes"); else puts("No"); return 0; }