QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#267301#2345. Karel the RobotTadijaSebezWA 1ms3688kbC++145.3kb2023-11-27 06:31:162023-11-27 06:31:17

Judging History

This is the latest submission verdict.

  • [2023-11-27 06:31:17]
  • Judged
  • Verdict: WA
  • Time: 1ms
  • Memory: 3688kb
  • [2023-11-27 06:31:16]
  • Submitted

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});
		if(known.count(state)){
			return known[state];
		}
		State newState=execute_priv(state);
		known[state]=newState;
		return newState;
	}

	int GetId(){
		return id;
	}

private:
	virtual State execute_priv(State state) = 0;

	int id;
	map<State,State> known;
};

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: 3668kb

Test #2:

score: 0
Accepted
time: 0ms
memory: 3636kb

Test #3:

score: 0
Accepted
time: 0ms
memory: 3568kb

Test #4:

score: 0
Accepted
time: 0ms
memory: 3688kb

Test #5:

score: -100
Wrong Answer
time: 0ms
memory: 3652kb