CCF-CSP 37-3 模板展开(templating)【C++】

题目

题目链接

TUOJhttps://sim.csp.thusaac.com/contest/37/problem/2参考:第37次CCF CSP第三题 模板展开 题解_模板展开csp-CSDN博客

思路

一、核心设计思想

系统将变量分为两种存储方式:

  1. 直接赋值:立即计算表达式结果并存储

  2. 间接赋值:存储表达式结构和依赖关系,查询时动态计算

二、变量存储结构

每个变量包含两个部分:

  • 固定值部分:所有直接字符串的长度总和

  • 依赖列表:引用的其他变量ID

这种设计允许表达式既包含字符串字面量,也包含对其他变量的引用。

三、三种操作详解

1. 操作1:直接赋值

处理流程

  • 立即计算所有部分的总和

  • 字符串字面量直接累加长度

  • 变量引用($开头)递归计算其当前值并累加

  • 将最终结果存入变量的固定值部分,清空依赖列表

特点:赋值时完成所有计算,后续查询直接返回值

2. 操作2:间接赋值

处理流程

  • 分离字符串和变量引用

  • 字符串字面量累加到固定值部分

  • 变量引用记录到依赖列表中

  • 不进行实际计算

特点:建立依赖关系网,查询时才计算

3. 操作3:查询变量值

处理流程

  • 检查缓存(len数组)

  • 若未缓存:固定值 + 递归计算所有依赖变量的值

  • 缓存结果后返回

四、计算与缓存机制

递归计算:

  • 对于间接赋值的变量,需要递归计算其依赖的所有变量

  • 自动处理多层嵌套的变量引用

缓存优化:

  • len数组缓存每个变量的计算结果

  • 每次操作开始时清空缓存(简单但低效)

  • 避免重复计算相同变量

代码

【对上面的代码按照自己的习惯进行了改写,但是逻辑基本一致】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define debug(a) cout<<"debug:"<<a<<endl;
const int N=2e3+5;
const int MOD=1e9+7;
int cnt=0; 

struct var{
//	int kind; //1:直接 2:间接 没用 
	ll l; //可能会爆int 
	vector<int>r; //依赖 
};

vector<var>v(N);
int len[N];
unordered_map<string,int>mp;

int get_idx(string s)
{
//	if(mp[s]!=NULL) ; //warn:不能mp[s]!=NULl来判断;写出mp[s]就会自动创建并赋值为0 
	if(mp.count(s)==0) mp[s]=cnt++; //这么判断才对 
	return mp[s];
}

int get_value(int idx) //传入下标 
{
	if(len[idx]!=-1) return len[idx];
	ll ans=v[idx].l;//int可能会爆 
	for(auto k:v[idx].r) 
	{
		//warn不能只加基础值,可能该变量间接引用的其他变量也是间接赋值,所以要递归计算 
		//ans=(ans+v[k].l)%MOD; 
		ans=(ans+get_value(k))%MOD; 
	}
	return ans;
}

void solve()
{
	int n; cin>>n;
	cin.get();
	while(n--)
	{
		memset(len,-1,sizeof(len)); //warn:应该是-1代表未计算 
		string line,s1;
		getline(cin,line); 
		stringstream ss(line);
		int op;
		ss>>op>>s1;
		int idx=get_idx(s1);
		if(op==1) //直接赋值 
		{
			v[idx].r.clear();
//			v[idx].l=0; //WARN:可以把自己直接赋值给自己 
			string now;
			ll res=0; //WARN:局部变量初始化 
			while (ss>>now)
			{
				if(now[0]=='$')
				{
					now.erase(0,1); //删$ 
					res=(res+get_value(get_idx(now)))%MOD;
				}
				else res=(res+now.size())%MOD; //WARN:不带$的是字面量不是变量 
			}
			v[idx].l=res;
		}
		else if(op==2) //间接赋值 
		{
			v[idx].r.clear();
			v[idx].l=0; //不会自己依赖自己,否则成环 
			
			ll res=0;
			string now;
			while (ss>>now)
			{
				if(now[0]=='$')
				{
					now.erase(0,1); //删$ 
					v[idx].r.push_back(get_idx(now));
				}
				else res=(res+now.size())%MOD;
			}
			v[idx].l=res;
		}		
		else if(op==3) cout<<get_value(idx)<<endl;
	}
}

int main()
{
	ios::sync_with_stdio(0),cin.tie(0);
	solve();
	return 0;	
} 
相关推荐
mu_guang_6 分钟前
算法图解3-递归
算法
散峰而望8 分钟前
【算法竞赛】C++入门(三)、C++输入输出初级 -- 习题篇
c语言·开发语言·数据结构·c++·算法·github
jianfeng_zhu12 分钟前
二叉排序树的建立和插入
算法
不会c嘎嘎15 分钟前
数据结构 -- 常见的八大排序算法
数据结构·c++·算法·排序算法·面试题·快速排序
REDcker26 分钟前
C++ 崩溃堆栈捕获库详解
linux·开发语言·c++·tcp/ip·架构·崩溃·堆栈
WW_千谷山4_sch32 分钟前
洛谷P8653:[模板] [蓝桥杯 2017 国 C] 分考场(染色最小色数)
c++·算法·蓝桥杯·深度优先
兵哥工控34 分钟前
MFC高精度方波发生器实现
c++·mfc
汉克老师1 小时前
GESP2025年12月认证C++五级真题与解析(判断题1-10)
c++·链表·贪心算法·排序·gesp5级·gesp五级
hk11241 小时前
【NLP/PatternRec】2026年度语义鸿沟分析与模糊模式识别基准索引 (Benchmark Index)
算法·自然语言处理·数据集·知识图谱·模式识别
hetao17338371 小时前
2025-12-31~2026-1-2 hetao1733837 的刷题笔记
c++·笔记·算法