QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#281321#2345. Karel the RobotTadijaSebezTL 753ms153980kbC++145.2kb2023-12-10 02:40:062023-12-10 02:40:06

Judging History

This is the latest submission verdict.

  • [2023-12-10 02:40:06]
  • Judged
  • Verdict: TL
  • Time: 753ms
  • Memory: 153980kb
  • [2023-12-10 02:40:06]
  • Submitted

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(){
		id=++tsz;
	}

	State execute(State state){
		//printf("id:%i state:(%i %i %c)\n",id,state.x,state.y,state.dir);
		if(active.count(state) || state.dir=='i'){
			return State(0,0,'i');
		}
		if(known.count(state)){
			state=known[state];
			return state;
		}
		active.insert(state);
		State newState=execute_priv(state);
		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;
};

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;

class FunctionCall : public Executable {
public:
	FunctionCall(char _fun) : Executable(), 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;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3864kb

Test #2:

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

Test #3:

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

Test #4:

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

Test #5:

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

Test #6:

score: 0
Accepted
time: 3ms
memory: 5832kb

Test #7:

score: 0
Accepted
time: 753ms
memory: 153980kb

Test #8:

score: 0
Accepted
time: 44ms
memory: 18336kb

Test #9:

score: -100
Time Limit Exceeded