QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#267300 | #2345. Karel the Robot | TadijaSebez | TL | 1ms | 4084kb | C++14 | 5.1kb | 2023-11-27 06:28:59 | 2023-11-27 06:29:00 |
Judging History
answer
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <cassert>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
const int N=150;
int r,c;
char mat[N][N];
bool inf=false;
struct State{
int x,y;
char dir;
State(){}
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;
vector<set<pair<int,State>>> was;
class Executable{
public:
Executable(){
id=++tsz;
}
State execute(State state){
//printf("id:%i state:(%i %i %c)\n",id,state.x,state.y,state.dir);
if(inf){
return state;
}
if(was.back().count({id,state})){
inf=true;
return state;
}
was.back().insert({id,state});
return execute_priv(state);
}
int GetId(){
return id;
}
private:
virtual State execute_priv(State state) = 0;
int id;
};
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(), 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(), 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;
set<pair<int,State>> stk;
class FunctionCall : public Executable {
public:
FunctionCall(char _fun) : Executable(), fun(_fun) {}
private:
State execute_priv(State state){
Executable* func = functions[fun];
if(stk.count({func->GetId(), state})){
inf=true;
return state;
}
stk.insert({func->GetId(), state});
was.push_back({});
state=func->execute(state);
was.pop_back();
stk.erase({func->GetId(), 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){
return b->execute(a->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));
}
int main(){
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);
//printf("Prog: %s\n",prog+1);
int sz=strlen(prog+1);
Executable* e=Parse(1,sz);
//printf("Parsed\n");
was.push_back({});
inf=false;
state=e->execute(state);
was.pop_back();
if(inf)printf("inf\n");
else printf("%i %i %c\n",state.x,state.y,state.dir);
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3872kb
Test #2:
score: 0
Accepted
time: 0ms
memory: 3792kb
Test #3:
score: 0
Accepted
time: 0ms
memory: 3816kb
Test #4:
score: 0
Accepted
time: 0ms
memory: 4084kb
Test #5:
score: 0
Accepted
time: 0ms
memory: 4072kb
Test #6:
score: -100
Time Limit Exceeded