1 条题解

  • 0
    @ 2025-5-25 23:49:26

    题意分析

    题目要求实现一个解释器,用于解析和执行“小被子语言”中的表达式。该语言包含两种原始被子 AABB,以及两个操作:

    1. turn(x)turn(x):将被子 xx 顺时针旋转 90 度。
    2. sew(x,y)sew(x, y):将被子 xx 缝合到被子 yy 的左侧,要求 xxyy 的高度相同,否则报错。

    原始被子 AABB 的初始形态如下:

    • A=///+A = \begin{matrix} / & / \\ / & + \end{matrix}
    • B=B = \begin{matrix} - & - \\ - & - \end{matrix}

    turn(x)turn(x) 操作的效果:

    • turn(A)turn(A)AA 顺时针旋转 90 度,得到   +/\begin{matrix} \ & \ \\ + & / \end{matrix}
    • turn(B)turn(B)BB 旋转 90 度,得到 \begin{matrix} | & | \\ | & | \end{matrix}

    sew(x,y)sew(x, y) 操作要求 xxyy 的高度相同,否则报错。例如:

    • sew(A,turn(B))sew(A, turn(B)) 是合法的,因为 AAturn(B)turn(B) 的高度均为 22
    • sew(turn(sew(B,turn(B))),A)sew(turn(sew(B, turn(B))), A) 会报错,因为 turn(sew(B,turn(B)))turn(sew(B, turn(B))) 的高度可能不等于 AA 的高度。

    解题思路

    1. 表达式解析

      • 输入可能跨越多行,需要忽略空格和换行符,提取完整的表达式(以 ; 结尾)。
      • 可以使用递归下降解析(Recursive Descent Parsing)或栈结构处理嵌套的 turnsew 操作。
    2. 被子表示

      • 每个被子可以用一个二维字符矩阵表示,初始 AABB 的矩阵已知。
      • 旋转操作 turn(x)turn(x) 需要实现矩阵的 90 度顺时针旋转。例如,对于一个 2×22 \times 2 矩阵: [ \begin{matrix} a & b \ c & d \end{matrix} \rightarrow \begin{matrix} c & a \ d & b \end{matrix} ]
      • 缝合操作 sew(x,y)sew(x, y) 需要检查两个矩阵的行数是否相同,然后进行水平拼接。
    3. 错误处理

      • sew(x,y)sew(x, y) 时,如果 xxyy 的高度不同,直接返回 error
      • 如果表达式语法错误(如括号不匹配),也应报错。
    4. 输出结果

      • 每个被子输出前需标注 Quilt i:,其中 ii 从 1 开始递增。
      • 如果解析或执行过程中出错,输出 error

    标程

    #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;
    }
    
    • 1

    信息

    ID
    2202
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    2
    上传者