码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 161E(搜索)

时间:2019-05-12 13:45:57      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:for   c++   矩阵   sizeof   ace   mat   tab   不用   void   

要点

  • 标签是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;
}

Codeforces 161E(搜索)

标签:for   c++   矩阵   sizeof   ace   mat   tab   不用   void   

原文地址:https://www.cnblogs.com/AlphaWA/p/10851967.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!