首页 > 编程语言 >洛谷 P5698 [CTSC1998]算法复杂度 题解

洛谷 P5698 [CTSC1998]算法复杂度 题解

时间:2022-10-25 14:55:15浏览次数:72  
标签:Node 洛谷 int 题解 CTSC1998 break continue child root

前言

咕了大半年,我回来了

说实话当鸽子的感觉挺不错???

原题链接

题意

给定一个伪代码,判断他总共需要进行几次操作,用多项式形式输出。

题解

首先,这是一道模拟题,发现性质的话比较水

输入及处理

对于 loopop

我们能够很容易的发现,对于任意的 loop 操作,与他有关的是在它上几层的 loop 以及在它下几层的 loopop,简单来说,整个伪代码可以看做一个一 begin 为根树形结构(暂时忽略 breakcontinue),以样例二为例,就像下图(忽略 breakcontinue

如此一来,我们只需要在读入时进行树形存储,最后扫描统计贡献就行

对于 breakcontinue

我们回忆一下 breakcontinue 的功能

  • break :结束本层循环
  • continue : 结束本次循环

很容易发现他们之间有几个共性

都只与本层循环有关,都改变了循环操作的对象,本层循环的剩余部分都变成了废话不会执行

那么对于 breakcontinue 操作,只需要忽略本层循环的剩余部分,对于 break , 再将循环次数改为1,就完成了对这两个操作的处理。用图表示就像下图(红色部分为发生变化的部分)

最终结构如下

因为题目没说总共有多少个 loopop 操作,所以存数据时最好用 vector指针 的方式存储,如下

点击查看代码
struct Node{
	int val;     //执行几次
	bool leaf;     //是否为叶节点,便于最后的统计
	Node*  father;      //父节点是哪个
	vector<Node> child;     //子节点有哪些
};
Node root;

while (1) {
		scanf ("%s", s + 1);
		if (s[1] == 'l') {
			scanf ("%s", s + 1);
			f -> child.push_back ((Node) {Change() % Mod, false, f});     //新建子节点
			f = &f -> child.back();     //准备开始下一层循环
		}
		else if (s[1] == 'o') {
			scanf ("%s", s + 1);
			f -> child.push_back ((Node) {Change() % Mod, true, f});
		}
		else if (s[1] == 'b') {
			if (f == &root) continue;
			f -> val = 1, f = f -> father;     //更改本层循环次数,并退回上一层循环
			TillEnd();     //忽略本层循环后续部分
		}
		else if (s[1] == 'c') {
			if (f == &root) continue;
			f = f -> father;
			TillEnd();
		}
		else if (s[1] == 'e') {
			if (f == &root) break;     //输入完毕
			f = f -> father;
		}
	}
`

细心的大佬看官可以发现,loopop 以及 breakcontinue 的处理极其相似,这也是我将他们放到一起分析的原因

统计

因为之前已经存好了树形结构,统计的时候只需要递归进行,传递系数和指数即可

点击查看代码
int ans[N];     //ans_i表示n的i次方的系数

void dfs(Node u, int pow, int coe) {
	if (u.leaf) {
		ans[pow] = (ans[pow] + coe) % Mod, maxn = max(maxn, pow);
		return;
	}
	for (int i = 0; i < u.child.size(); ++i)
		(u.child[i].val == -1) ? dfs(u.child[i], pow + 1, coe % Mod) : dfs(u.child[i], pow, coe * u.child[i].val % Mod);
}
点击查看代码

输出

从高到低输出即可,注意判系数为1及指数为1或0的情况

就下来是喜闻乐见的

全部代码

点击查看代码
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int N = 20 + 10;
const int Mod = 998244353;
struct Node{
	int val;
	bool leaf;
	Node*  father;
	vector<Node> child;
};
Node root;
int ans[N];
char s[N];
int maxn;
inline int read() {
    int s = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return s * f;
}
inline void write(int x) {
    if (x < 0) putchar('-'), x = ~(x - 1);
    int s[50], top = 0;
    while (x) s[++top] = x % 10, x /= 10;
    if (top == 0) s[++top] = 0;
    while (top) putchar(s[top--] + '0');
}
inline int max(int x, int y) { return x > y ? x : y; }
inline int Change() {
	if (s[1] == 'n') return -1;
	int n = strlen(s + 1), number = 0;
	for (int i = 1; i <= n; ++i) number = (number << 3) + (number << 1) + (s[i] ^ 48);
	if (number == 0) return -1;
	return number % Mod;
}
inline void TillEnd() {
	int cnt = 1;
	while (cnt) {
		scanf ("%s", s + 1);
		if (s[1] == 'l') ++cnt;
		else if (s[1] == 'e') --cnt;
	}
}
void dfs(Node u, int pow, int coe) {
	if (u.leaf) {
		ans[pow] = (ans[pow] + coe) % Mod, maxn = max(maxn, pow);
		return;
	}
	for (int i = 0; i < u.child.size(); ++i)
		(u.child[i].val == -1) ? dfs(u.child[i], pow + 1, coe % Mod) : dfs(u.child[i], pow, coe * u.child[i].val % Mod);
}
inline void print(int pos) {
	if (ans[pos] == 1) {
		if (pos == 0) printf ("1");
		if (pos == 1) printf ("n");
		if (pos >= 2) printf ("n^%d", pos);
	}
	else {
		if (pos == 0) printf ("%d", ans[pos]);
		if (pos == 1) printf ("%dn", ans[pos]);
		if (pos >= 2) printf ("%dn^%d", ans[pos], pos);
	}
}
int main() {
	root.val = 0, root.leaf = false, root.father = NULL;
	Node* f = &root;
	while (1) {
		scanf ("%s", s + 1);
		if (s[1] == 'l') {
			scanf ("%s", s + 1);
			f -> child.push_back ((Node) {Change() % Mod, false, f});
			f = &f -> child.back();
		}
		else if (s[1] == 'o') {
			scanf ("%s", s + 1);
			f -> child.push_back ((Node) {Change() % Mod, true, f});
		}
		else if (s[1] == 'b') {
			if (f == &root) continue;
			f -> val = 1, f = f -> father;
			TillEnd();
		}
		else if (s[1] == 'c') {
			if (f == &root) continue;
			f = f -> father;
			TillEnd();
		}
		else if (s[1] == 'e') {
			if (f == &root) break;
			f = f -> father;
		}
	}
	dfs(root, 0, 1);
	print(maxn);
	for (int i = maxn - 1; i >= 0; --i)
		if (ans[i]) printf ("+"), print(i);
	printf ("\n");
	return 0;
}

P.S.

数据里有一个小锅,没注意会WA一个点,那就请各位看官自行去找喽~~

标签:Node,洛谷,int,题解,CTSC1998,break,continue,child,root
From: https://www.cnblogs.com/Nebula-Astraea/p/16767326.html

相关文章

  • 【问题解决】win10显示器扩展设置及接口辨析
    问题描述电脑多屏显示主机接口辨析win10设置开始(左下角)--设置(小齿轮):点击系统(显示、通知、应用、电源):点击显示或屏幕:扩展屏幕:横向,扩展这些......
  • CF1732D2 Balance (Hard version) 题解
    前天打了波CF结果怒掉100分,果然退化得太厉害了,遂于昨晚补题.题面维护一个集合SS,有三种操作:插入一个数、删除一个数、查询kk的倍数中没出现过的最小的数。思路考......
  • LeetCode2447 最大公因数等于 K 的子数组数目 题解
    看到这题,发现可以直接枚举字串进行check,复杂度是\(\mathcalO(n^2(n+\logw))\),但是可以固定左端点,向右推右端点统计答案优化到\(\mathcalO(n(n+\logw))\)。虽然这里......
  • 洛谷 P3401
    甚么神仙题啊……#include<iostream>#include<vector>#include<cstdio>#include<cstring>#include<iterator>#include<utility>#defineintlonglongusin......
  • P6533 RELATIVNOST 题解
    P6533RELATIVNOST题解目录P6533RELATIVNOST题解题目分析思路代码题目洛谷P6533RELATIVNOST分析题目中要求至少有\(c\)人买走至少一张彩色画,那暴力的思路就是......
  • 【题解】ABC259Ex Yet Another Path Counting
    Sol考虑两种暴力。直接枚举同类点,组合数计算两点之间的路径数。单次操作时间复杂度\(O(B^2)\)。其中\(B\)表示这类点的个数。暴力dp,记\(dp_{i,j}\)表示到\((i,j......
  • Codeforces Round #829-1754A+B与1753A+B+C 题解
    1754A-TechnicalSupport题意给定一个只包含大写字母\(\texttt{Q}\)和\(\texttt{A}\)的字符串,如果字符串里的每一个\(\texttt{Q}\)都能与在其之后的\(\texttt{A......
  • 【题解】ABC259F Select Edges
    Sol考虑dp。记\(dp_{u,0/1}\)表示\(u\)点是否向上连边的最大值。转移的话相当于是找若干个\(dp_{v,1}+w(u,v)\)进行转移。其中\(w(u,v)\)表示\((u,v)\)这条......
  • 2022级HAUT新生周赛题解汇总
    2022级HAUT新生周赛(零)题解@:2022级HAUT新生周赛(一)题解@卞子骏:2022级HAUT新生周赛(二)题解@武其轩:2022级HAUT新生周赛(三)题解@焦小航:2022级HAUT新生周赛(四)题解@张子豪:202......
  • leetcode刷题MySQL题解十八
    leetcode刷题MySQL题解十八题目叙述Views表:±--------------±--------+|ColumnName|Type|±--------------±--------+|article_id|int||author_id|int|......