首页 > 代码库 > UVA 1423 - Guess(拓扑排序)

UVA 1423 - Guess(拓扑排序)

UVA 1423 - Guess

题目链接

题意:给定一个每个区间和的正负,构造一个序列,使得满足这个矩阵

思路:每个区间和等于两个前缀和的差,这样就可以知道每两个前缀和的大小关系,利用拓扑排序可以求出顺序,然后对应要控制不超过|10|,所以从-10开始,大的就+1,然后构造出这个前缀和序列,对应每个ai就等于c[i] - c[i - 1]

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

int t, n, du[15], ans[15], tmp[15], tn;
char str[105];
vector<int> g[15];
queue<int> Q;

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%s", &n, str);
		int sn = 0;
		while (!Q.empty()) Q.pop();
		for (int i = 0; i <= n; i++) {
			du[i] = 0;
			g[i].clear();
		}
		for (int i = 1; i <= n; i++) {
			for (int j = i; j <= n; j++) {
				if (str[sn] == '+') {
					g[i - 1].push_back(j);
					du[j]++;
				}
				else if (str[sn] == '-') {
					g[j].push_back(i - 1);
					du[i - 1]++;
				}
				sn++;
			}
		}
		for (int i = 0; i <= n; i++)
			if (du[i] == 0) Q.push(i);
		int cnt = -10;
		while (!Q.empty()) {
			tn = 0;
			while (!Q.empty()) {
				tmp[tn] = Q.front();
				ans[tmp[tn]] = cnt;
				tn++;
				Q.pop();
			}
			for (int i = 0; i < tn; i++) {
				int u = tmp[i];
				for (int j = 0; j < g[u].size(); j++) {
					du[g[u][j]]--;
					if (du[g[u][j]] == 0)
						Q.push(g[u][j]);
				}
			}
			cnt++;
		}
		for (int i = 1; i <= n; i++) {
			printf("%d%c", ans[i] - ans[0] - (ans[i - 1] - ans[0]), i == n ? '\n' : ' ');
		}
	}
	return 0;
}


UVA 1423 - Guess(拓扑排序)