专栏文章

题解:P1037 [NOIP2002 普及组] 产生数

P1037题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqdpyv8
此快照首次捕获于
2025/12/04 03:07
3 个月前
此快照最后确认于
2025/12/04 03:07
3 个月前
查看原文

题解

P1037

题目思路:

  1. 输入处理:读取输入值,包括整数 n 和变换规则。
  2. 图的构建:使用邻接表表示变换规则,其中每个节点(数字)指向它可以变换成的其他节点(数字)。
  3. 可达性计算:对于每个数字(0\texttt0~9\texttt9),使用广度优先搜索(BFS)计算所有可达数字。这有助于确定每个数字在经过任意次数变换后可以变换成的数字数量。
  4. 结果计算:将整数 n 转换为字符串,以便逐个处理每个数字。使用高精度乘法方法,将 n 中每个数字的可达数字数量相乘,以处理较大的结果。

AC Code:

CPP
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>
#include <string>
#include <algorithm>
using namespace std;

string multiply(const string& a, int b) {
	if (b == 0) return "0";
	string res;
	int carry = 0;
	for (int i = a.size() - 1; i >= 0; --i) {
		int product = (a[i] - '0') * b + carry;
		res.push_back(product % 10 + '0');
		carry = product / 10;
	}
	if (carry > 0) {
		res.push_back(carry + '0');
	}
	reverse(res.begin(), res.end());
	size_t start = res.find_first_not_of('0');
	if (start != string::npos) {
		return res.substr(start);
	} else {
		return "0";
	}
}

int main() {
	string n;
	int k;
	cin >> n >> k;

	vector<vector<int>> adj(10);

	for (int i = 0; i < k; ++i) {
		int x, y;
		cin >> x >> y;
		adj[x].push_back(y);
	}

	int size[10];
	for (int d = 0; d < 10; ++d) {
		unordered_set<int> visited;
		queue<int> q;
		q.push(d);
		visited.insert(d);

		while (!q.empty()) {
			int u = q.front();
			q.pop();

			for (int v : adj[u]) {
				if (visited.find(v) == visited.end()) {
					visited.insert(v);
					q.push(v);
				}
			}
		}
		size[d] = visited.size();
	}

	string result = "1";
	for (char c : n) {
		int d = c - '0';
		result = multiply(result, size[d]);
	}

	cout << result << endl;

	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...