UVA1423 Guess

题意

给定一个半邻接矩阵 Si,jS_{i,j},每个 Si,jS_{i,j} 表示 x=ijax\sum_{x=i}^j a_x 的正负性,有正数,负数,00 三种可能,现在给定矩阵 SS,求任意一个可行的 aa 序列,其中 10ai10-10 \le a_i \le 10

解法

据说正解是拓扑排序,但是注意到 n10n \le 10,那么其实爆搜加剪枝可以过。

考虑如何剪枝,剪枝其实就是判定 aia_i 的值时只需要枚举所有 Sx,iS_{x,i},其中 xix \le i。因为所有 Sx,k(x<i,k<i)S_{x, k}(x <i, k < i) 都已经在前面的搜索中判定过。

上代码:

#pragma GCC optimize("-Ofast")
#pragma GCC target("avx,sse,sse2,sse3,sse4")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 15;

int t, n;
char c[N][N];
int a[N];

inline int read()
{
	register char ch = getchar();
	register int x = 0;
	while (ch < '0' || ch > '9') ch = getchar();
	while (ch >= '0' and ch <= '9')
	{
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x;
}

inline void write(int x)
{
	if (x < 0)
	{
		putchar('-');
		x = -x;
	}
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}

inline bool dfs(int dep)
{
	if (dep > n)
	{
		for (register int i = 1; i <= n; i++)
		{
			write(a[i]);
			putchar(' ');
		}
		return true;
	}
	register int sum = 0;
	for (register int i = 1; i < dep; i++) sum += a[i];
	for (register int i = -10; i <= 10; i++)
	{
		a[dep] = i;
		sum += i;
		register int sumx = 0;
		for (register int j = 1; j <= dep; j++)
		{
			register int ex = sum - sumx;
			if ((ex < 0 && c[j][dep] != '-') || (ex == 0 && c[j][dep] != '0') || (ex > 0 && c[j][dep] != '+'))
			{
				goto Nxt;
			}
			sumx += a[j];
		}
		if (dfs(dep + 1)) return true;
	Nxt:
		sum -= i;
	}
	return false;
}

int main()
{
	t = read();
	while (t--)
	{
		n = read();
		for (register int i = 1; i <= n; i++)
		{
			for (register int j = i; j <= n; j++) cin >> c[i][j];
		}
		dfs(1);
		putchar('\n');
	}
	return 0;
}
posted @   HappyBobb  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示