1. 程式人生 > 實用技巧 >POJ 3201-Little Quilt(大模擬)

POJ 3201-Little Quilt(大模擬)

題目連線:http://poj.org/problem?id=3201
CSDN食用連結:https://blog.csdn.net/qq_43906000/article/details/109367484
Time Limit: 1000MS Memory Limit: 65536K

Description

Little Quilt is a small language introduced by Ravi Sethi in his book ‘Programming Languages’. Here, a restricted version of Little Quilt is presented.

The language is defined by the following BNF grammar:

<QUILT> ::= A | B | turn(<QUILT>) | sew(<QUILT>,<QUILT>)

A and B represent the two primitive quilts. Each primitive quilt corresponds to a matricial arrangement of 2 × 2 characters. turn() and sew() are operations over quilts.

The instruction turn(x) turns the quilt x 90 degrees clockwise. The following table illustrates the primitive quilts as well as examples of the effect of the turn() operation:

A   			//
				/+
/*----------------------------------*/
turn(A)			\\
				+\
/*---------------------------------*/
turn(turn(A))	+/
				//
/*---------------------------------*/
turn(turn(turn(A)))\+
				   \\
/*---------------------------------*/
B					--
					--
/*---------------------------------*/
turn(B)				||
					||									   

Accordingly, the instruction sew(x,y) sews quilt x to the left of quilt y. Both x and y must have the same height, otherwise an error will be generated. The following figure represents the result of sew(A,turn(B)):

//||
/+||

while the sew(turn(sew(B,turn(B))),A) generates an error message.

Your job is to build an interpreter of the Little Quilt language.

Input

The input file will be a text file containing different Little Quilt expressions, each one ended by a semicolon character\((;)\). Space and new line characters must be ignored; this means that an expression may span several lines.

Output

The output file contains the quilts produced as a result of interpreting the input expressions.

Each quilt must be preceded by a line, left aligned, with the format

Quilt i:

where i is the quilt number, starting at 1. If the expression interpretation generates and error, the word

error

must be printed.

Sample Input

sew(turn(sew(B,turn(B))),
turn(sew(turn(B),B))) ;

sew(turn(sew(B,turn(B))),A);
sew(turn(sew(A,turn(A))),
turn(turn(

turn(sew(A,turn(A))))))

;
Sample Output

Quilt 1:
||--
||--
--||
--||
Quilt 2:
error
Quilt 3:
\//
+/+
+/+
//\

題目大意:
給出一種簡單語言 有兩種操作語句(旋轉,連結)和兩個基本單元。
要求將給出的該語言的語句翻譯成對應的符號矩陣。每句話是以分號為結尾的,對於每句話翻譯一個符號矩陣。

emmm,幾百年前寫的程式碼了,用結構體封裝一些操作後就可以比較簡單地模擬了。根據給出的語句將之翻譯成語法樹,然後再計算就可以了。

以下是AC程式碼:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
char the_ch[] = { '/','\\','-','|','+','+' };
string ss;
int tot;
struct point {
	int x, y, ch;
	point() {}
	point(int x, int y, int ch) :x(x), y(y), ch(ch) {}
	bool operator <(const point& a)const {
		if (a.x == x) return a.y > y;
		return a.x > x;
	}
};
struct node
{
	vector<point>vs;
	int h, w;
	void turns() {
		swap(h, w);
		for (int i = 0; i < vs.size(); i++) {
			swap(vs[i].x, vs[i].y);
			vs[i].y = w - vs[i].y - 1;
			vs[i].ch ^= 1;
		}
	}
	int ok_sew(node& s) {
		if (s.h != h) return 0;
		for (int i = 0; i < s.vs.size(); i++) {
			vs.push_back(point(s.vs[i].x, s.vs[i].y + w, s.vs[i].ch));
		}
		w += s.w;
		return 1;
	}
	void print() {
		sort(vs.begin(), vs.end());
		int num = 0;
		for (int i = 0; i < vs.size(); i++) {
			cout << the_ch[vs[i].ch];
			num++;
			if (num == w) num = 0, cout << endl;
		}
	}
};
node a, b;
node quilt[10000];
int build(string& s, int& rt, int now);
int main()
{
	//freopen("in.txt", "r", stdin);
	char ch;
	int cas = 0;
    a.w = a.h = b.w = b.h = 2;
	a.vs.push_back(point(0, 0, 0)); a.vs.push_back(point(0, 1, 0));
	a.vs.push_back(point(1, 0, 0)); a.vs.push_back(point(1, 1, 4));
	b.vs.push_back(point(0, 0, 2)); b.vs.push_back(point(0, 1, 2));
	b.vs.push_back(point(1, 0, 2)); b.vs.push_back(point(1, 1, 2));
	while (ch = getchar()) {
		if (ch == EOF) return 0;
		if (ch != ';') {
			ss += ch;
		}
		else {
			string p = "\0";
			string np;
			int len = ss.size();
			for (int i = 0; i < len; i++) {
				if (ss[i] == 'A') np += 'A';
				else if (ss[i] == 'B') np += 'B';
				else if (ss[i] == 's') np += 'S';
				else if (ss[i] == 't') np += 'T';
			}
			ss = p; tot = 0;
			int idx = 0;
			cout << "Quilt " << ++cas << ":\n";
			if (build(np, idx, 0)) quilt[0].print();
			else cout << "error" << endl;
		}
	}
	return 0;
}
int build(string& s, int& rt, int now)
{
	int ans = 1;
	if (s[rt] == 'A') quilt[now] = a;
	else if (s[rt] == 'B') quilt[now] = b;
	else if (s[rt] == 'T') {
		rt++;
		int lson = rt;
		tot++;
		ans = build(s, rt, tot);
		quilt[lson].turns();
		quilt[now] = quilt[lson];
	}
	else if (s[rt] == 'S') {
		rt++;
		int lson = rt;
		tot++;
		ans = build(s, rt, tot);
		quilt[now] = quilt[lson];
		rt++;
		int rson = rt;
		tot++;
		ans = (ans && build(s, rt, tot));
		ans = (ans && quilt[now].ok_sew(quilt[rson]));
	}
	return ans;
}