Codeforces 161E(搜索)

要点

  • 标签是dp但搜索一发就能过了。
  • 因为是对称矩阵所以试填一下就是一个外层都填满了,因此搜索的深度其实不超过5。
  • 显然要预处理有哪些素数。在这个过程中可以顺便再处理出一个\(vector:re[len][number]\),表示前面已经填了长度为len的数为number,那么最后会合法的填法应该在后面填什么数字。这么预处理之后会发现dfs时就很好枚举了。
  • 一个处理技巧是把数填在右下角而不是从坐标1开始填,这样我们的re数组就不用多加一维了:免去了目前矩阵的最大长度这一维。
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

const int maxn = 1e5 + 5;
int T, p, len, ans;
int vis[maxn], table[6][6];
vector<int> re[6][maxn];

void Fill(int st, int k) {
	for (int i = 5; i >= st; i--, k /= 10) {
		table[st][i] = table[i][st] = k % 10;
	}
}

void Pre() {
	for (int i = 2; i < maxn - 5; i++) {
		if (!vis[i]) {
			for (int j = i * 2; j < maxn - 5; j += i)
				vis[j] = 1;
			for (int k = i, t = 1, j = 4; j; j--) {
				t *= 10; k /= 10;
				re[j][k].push_back(i % t);
			}
		}
	}
}

void dfs(int depth, int tmp = 0) {
	if (depth > 5)	{
		ans++;
		return;
	}

	for (int i = 1; i < depth; i++)
		tmp = tmp * 10 + table[depth][i];
	for (int i : re[depth - 1][tmp]) {
		Fill(depth, i);
		dfs(depth + 1);
	}
}

int main() {
	Pre();
	for (scanf("%d", &T); T; T--) {
		scanf("%d", &p);
		memset(table, 0, sizeof table);
		ans = len = 0;
		for (int k = p; k; k /= 10, len++);
		Fill(5 - len + 1, p);
		dfs(5 - len + 2);
		printf("%d\n", ans);
	}
	return 0;
}
posted @ 2019-05-12 13:20  AlphaWA  阅读(181)  评论(0编辑  收藏  举报