QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#281328 | #2345. Karel the Robot | TadijaSebez | TL | 27ms | 5260kb | C++14 | 5.3kb | 2023-12-10 02:45:36 | 2023-12-10 02:45:37 |
Judging History
answer
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <cassert>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <ctime>
using namespace std;
const int N=150;
int r,c;
char mat[N][N];
struct State{
int x,y;
char dir;
State(){}
State(int _x,int _y,char _dir):x(_x),y(_y),dir(_dir){}
bool operator < (const State& other) const {
if(x!=other.x)return x<other.x;
if(y!=other.y)return y<other.y;
return dir<other.dir;
}
};
int tsz;
class Executable{
public:
Executable(bool _cache=false){
id=++tsz;
cache=_cache;
}
State execute(State state){
if(active.count(state) || state.dir=='i'){
return State(0,0,'i');
}
if(cache){
if(known.count(state)){
state=known[state];
return state;
}
active.insert(state);
}
State newState=execute_priv(state);
if(cache){
active.erase(state);
known[state]=newState;
}
return newState;
}
int GetId(){
return id;
}
private:
virtual State execute_priv(State state) = 0;
int id;
map<State,State> known;
set<State> active;
bool cache;
};
State MoveState(State state){
int x=state.x,y=state.y;
if(state.dir=='n'){
x--;
}else if(state.dir=='s'){
x++;
}else if(state.dir=='e'){
y++;
}else if(state.dir=='w'){
y--;
}
if(mat[x][y]!='#'){
state.x=x;
state.y=y;
}
return state;
}
class Move : public Executable {
public:
Move() : Executable() {}
private:
State execute_priv(State state){
return MoveState(state);
}
};
class TurnLeft : public Executable {
public:
TurnLeft() : Executable() {}
private:
State execute_priv(State state){
if(state.dir=='n'){
state.dir='w';
}else if(state.dir=='s'){
state.dir='e';
}else if(state.dir=='e'){
state.dir='n';
}else if(state.dir=='w'){
state.dir='s';
}
return state;
}
};
bool Check(char condition, const State& state){
bool cond;
if(condition=='b'){
State mv=MoveState(state);
cond=(mv.x==state.x && mv.y==state.y);
}else{
cond=(state.dir==condition);
}
return cond;
}
class If : public Executable {
public:
If(char _condition, Executable* _pos, Executable* _neg) : Executable(true), condition(_condition), pos(_pos), neg(_neg) {}
private:
State execute_priv(State state){
if(Check(condition,state))return pos->execute(state);
else return neg->execute(state);
}
char condition;
Executable* pos;
Executable* neg;
};
class Loop : public Executable {
public:
Loop(char _condition, Executable* _e) : Executable(true), condition(_condition), e(_e) {}
private:
State execute_priv(State state){
if(!Check(condition,state)){
state=e->execute(state);
return this->execute(state);
}
return state;
}
char condition;
Executable* e;
};
map<char, Executable*> functions;
class FunctionCall : public Executable {
public:
FunctionCall(char _fun) : Executable(true), fun(_fun) {}
private:
State execute_priv(State state){
Executable* func = functions[fun];
state=func->execute(state);
return state;
}
char fun;
};
class Compose : public Executable {
public:
Compose(Executable* _a, Executable* _b) : Executable(), a(_a), b(_b) {}
private:
State execute_priv(State state){
state=a->execute(state);
return b->execute(state);
}
Executable* a;
Executable* b;
};
class Empty : public Executable {
public:
Empty() : Executable() {}
private:
State execute_priv(State state){
return state;
}
};
const int M=250;
char prog[M];
int First(int start){
assert(prog[start]=='(');
int bal=1;
start++;
while(bal!=0){
if(prog[start]=='(')bal++;
if(prog[start]==')')bal--;
start++;
}
return start;
}
Executable* Parse(int l,int r){
if(l>r)return new Empty();
Executable* main;
int offset;
if(prog[l]=='m'){
main=new Move();
offset=1;
}else if(prog[l]=='l'){
main=new TurnLeft();
offset=1;
}else if(prog[l]=='i'){
int ptr=First(l+2);
Executable* pos=Parse(l+3,ptr-2);
int ptr2=First(ptr);
Executable* neg=Parse(ptr+1,ptr2-2);
main=new If(prog[l+1],pos,neg);
offset=ptr2-l;
}else if(prog[l]=='u'){
int ptr=First(l+2);
Executable* e=Parse(l+3,ptr-2);
main=new Loop(prog[l+1],e);
offset=ptr-l;
}else{
main=new FunctionCall(prog[l]);
offset=1;
}
l+=offset;
if(l>r)return main;
return new Compose(main,Parse(l,r));
}
State ans[50];
int main(){
clock_t before=clock();
int d,e;
scanf("%i %i %i %i",&r,&c,&d,&e);
for(int i=1;i<=r;i++){
scanf("%s",mat[i]+1);
}
for(int i=0;i<=c+1;i++){
mat[0][i]='#';
mat[r+1][i]='#';
}
for(int i=0;i<=r+1;i++){
mat[i][0]='#';
mat[i][c+1]='#';
}
for(int i=1;i<=d;i++){
scanf("%s",prog+1);
int sz=strlen(prog+1);
functions[prog[1]]=Parse(3,sz);
}
for(int i=1;i<=e;i++){
State state;
scanf("%i %i %c",&state.x,&state.y,&state.dir);
scanf("%s",prog+1);
int sz=strlen(prog+1);
Executable* e=Parse(1,sz);
state=e->execute(state);
ans[i]=state;
}
clock_t after=clock();
//if((after-before)*2 > CLOCKS_PER_SEC) {
// for(int i=1;i<=e;i++)ans[i].dir='i';
//}
for(int i=1;i<=e;i++){
if(ans[i].dir=='i')printf("inf\n");
else printf("%i %i %c\n",ans[i].x,ans[i].y,ans[i].dir);
}
return 0;
}
Details
Test #1:
score: 100
Accepted
time: 1ms
memory: 4044kb
Test #2:
score: 0
Accepted
time: 0ms
memory: 3980kb
Test #3:
score: 0
Accepted
time: 0ms
memory: 4036kb
Test #4:
score: 0
Accepted
time: 0ms
memory: 3976kb
Test #5:
score: 0
Accepted
time: 0ms
memory: 3848kb
Test #6:
score: 0
Accepted
time: 27ms
memory: 5260kb
Test #7:
score: -100
Time Limit Exceeded