QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#281334#2345. Karel the RobotTadijaSebezAC ✓1160ms224920kbC++146.0kb2023-12-10 02:54:312023-12-10 02:54:32

Judging History

This is the latest submission verdict.

  • [2023-12-10 02:54:32]
  • Judged
  • Verdict: AC
  • Time: 1160ms
  • Memory: 224920kb
  • [2023-12-10 02:54:31]
  • 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];

int dir_to_int(char dir){
	if(dir=='n')return 0;
	if(dir=='s')return 1;
	if(dir=='e')return 2;
	if(dir=='w')return 3;
}

char dir_from_int(int val){
	if(val==0)return 'n';
	if(val==1)return 's';
	if(val==2)return 'e';
	if(val==3)return 'w';
}

const int lim=40*40*4+1;
struct State{
	int x,y;
	char dir;

	State(){}
	State(int _x,int _y,char _dir):x(_x),y(_y),dir(_dir){}

	static State from_int(int val){
		State ans;
		if(val==0){
			ans.x=0;
			ans.y=0;
			ans.dir='i';
		}else{
			val--;
			ans.dir=dir_from_int(val%4);
			val/=4;
			ans.y=val%40+1;
			val/=40;
			ans.x=val+1;
		}
		return ans;
	}

	int to_int(){
		if(dir=='i')return 0;
		return 1+(x-1)*40*4+(y-1)*4+dir_to_int(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=true;//_cache;
		for(int i=0;i<lim;i++){
			known[i]=-1;
			active[i]=false;
		}
	}

	State execute(State state){
		if(active[state.to_int()] || state.dir=='i'){
			return State(0,0,'i');
		}
		if(cache){
			if(known[state.to_int()]!=-1){
				state=State::from_int(known[state.to_int()]);
				return state;
			}
			active[state.to_int()]=true;
		}
		State newState=execute_priv(state);
		if(cache){
			active[state.to_int()]=false;
			known[state.to_int()]=newState.to_int();
		}
		return newState;
	}

	int GetId(){
		return id;
	}

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

	int id;
	int known[lim];
	bool active[lim];
	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;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 5984kb

Test #2:

score: 0
Accepted
time: 1ms
memory: 6668kb

Test #3:

score: 0
Accepted
time: 1ms
memory: 4864kb

Test #4:

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

Test #5:

score: 0
Accepted
time: 1ms
memory: 4624kb

Test #6:

score: 0
Accepted
time: 8ms
memory: 158472kb

Test #7:

score: 0
Accepted
time: 180ms
memory: 190412kb

Test #8:

score: 0
Accepted
time: 11ms
memory: 77764kb

Test #9:

score: 0
Accepted
time: 1160ms
memory: 224876kb

Test #10:

score: 0
Accepted
time: 1ms
memory: 6056kb

Test #11:

score: 0
Accepted
time: 1ms
memory: 5272kb

Test #12:

score: 0
Accepted
time: 1ms
memory: 6308kb

Test #13:

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

Test #14:

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

Test #15:

score: 0
Accepted
time: 11ms
memory: 132948kb

Test #16:

score: 0
Accepted
time: 8ms
memory: 129284kb

Test #17:

score: 0
Accepted
time: 1104ms
memory: 219568kb

Test #18:

score: 0
Accepted
time: 1109ms
memory: 224920kb

Test #19:

score: 0
Accepted
time: 24ms
memory: 111164kb

Test #20:

score: 0
Accepted
time: 176ms
memory: 105880kb