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;
}