///
题意:字典中总共有w个单词.b次询问.每次给出一个4*4的字符矩阵.
可以从矩阵中任意一个位置开始.往相邻8个方向走.最后组成一个单词.
若组成的单词在字典中,则按其长度来计算分数. 
长度3,4积分为1.长度5积分2.长度6积分3.长度7积分5.长度8积分11.
字典中的单词长度最多为8.矩阵中的同一个位置在一个单词中只能出现一次.可以被多个单词使用.
w<=3e5.b<=30.字典中一个单词只算一次分数.问最多能得到多少积分?

暴力dfs计算出矩阵能组成的所有单词.并用map标记即可.
字典中的单词长度最多为8 所以复杂度在O(8^8 *30).实际比较快 暴力水过.
正解:
因为dfs搜索时很多单词明显不在字典中.
可以先用Trie存字典单词.dfs暴力时若当前t不是任意一个单词前缀直接返回即可.复杂度为O(3e5*8*30)

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
const int N=2e2+5,M=4e6+5;
int T;
bool vis[N][N];
int dx[]={-1,-1,1,1};
int dy[]={-1,1,-1,1};
ii pre[N][N];
void bfs(int sx,int sy,int ex,int ey){queue<ii> q;q.push(ii(sx,sy));
//  cout<<sx<<' '<<sy<<' ';memset(vis,0,sizeof(vis));vis[sx][sy]=true;pre[sx][sy]=ii(0,0);while(!q.empty()){int x=q.front().first,y=q.front().second;q.pop();for(int i=0;i<4;i++){for(int j=1;j<=8;j++){int nx=x+dx[i]*j,ny=y+dy[i]*j;if(nx>=1&&nx<=8&&ny>=1&&ny<=8&&!vis[nx][ny]){vis[nx][ny]=true;pre[nx][ny]=ii(x,y);q.push(ii(nx,ny));} }}}if(!vis[ex][ey])  cout<<"Impossible"<<'\n';else{stack<ii> stk;ii now=ii(ex,ey);while(now.first!=0){stk.push(now);ii tmp=pre[now.first][now.second];now=tmp;}printf("%d",stk.size()-1);while(!stk.empty()){int x=stk.top().first,y=stk.top().second;stk.pop(); printf(" %c %d",'A'+x-1,y);}printf("\n");}
}
int main(){cin>>T;while(T--){char a[20],b[20];int sy,ey;scanf("%s%d%s%d",a,&sy,b,&ey);int sx=a[0]-'A'+1;int ex=b[0]-'A'+1;bfs(sx,sy,ex,ey);}return 0;
} 

正解:

// @EXPECTED_RESULTS@: CORRECT#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <algorithm>
#include <assert.h>using namespace std;int numWords, numBoggles;
vector<string> dictionary;
string boggle[4];
bool vis[4][4];
vector<string> found;int dx[] = { 0, 0,-1,-1,-1,+1,+1,+1};
int dy[] = {-1,+1,-1, 0,+1,-1, 0,+1};
int toScore[] = {0, 0, 0, 1, 1, 2, 3, 5, 11, 11, 11, 11, 11, 11, 11, 11, 11};struct trie {bool valid;int edges[26];int last;
};#define MAX_TRIE (5+8*300000)
trie tries[MAX_TRIE];
int edgeCnt;
int kase;int init() {int id = edgeCnt;tries[id].valid = false;for (int i = 0; i < 26; i++) tries[id].edges[i] = -1;edgeCnt++;assert(edgeCnt < MAX_TRIE);return id;
}void add(int id, string &w, int idx) {if (idx >= (signed) w.size()) {tries[id].valid = true;return;}int letter = (int) (w[idx] - 'A');if (tries[id].edges[letter] == -1) {tries[id].edges[letter] = init();}add(tries[id].edges[letter], w, idx + 1);
}void rec(int i, int j, string cur, int id) {if (i < 0 || j < 0 || i >= 4 || j >= 4) return;if (vis[i][j]) return;if (cur.size() >= 8) return;vis[i][j] = true;cur = cur + boggle[i][j];int letter = (int) (boggle[i][j] - 'A');int next = tries[id].edges[letter];if (next == -1) {vis[i][j] = false;return;}if (tries[next].valid && tries[next].last < kase) {tries[next].last = kase;found.push_back(cur);
//      cerr << "found " << cur << endl;}for (int c = 0; c < 8; c++) {rec(i + dx[c], j + dy[c], cur, next);}vis[i][j] = false;
}int main() {edgeCnt = 0;int root = init();cin >> numWords;for (int i = 0; i < numWords; i++) {string t;cin >> t;add(root, t, 0);}cin >> numBoggles;for (int i = 0; i < numBoggles; i++) {kase = i + 1;for (int j = 0; j < 4; j++) cin >> boggle[j];found.clear();for (int j = 0; j < 4; j++) {for (int k = 0; k < 4; k++) {rec(j,k, "", root);}}string best = *(found.begin());int score = 0;for (vector<string>::iterator iter = found.begin(); iter != found.end(); iter++) {if (best.size() < iter->size() || (best.size() == iter->size() && *iter < best)) {best = *iter;}score += toScore[iter->size()];}cout << score << " " << best << " " << found.size() << endl;}return 0;
}

GCPC 13 A Boggle 暴力,Trie剪枝相关推荐

  1. CF-557 E. Ann and Half-Palindrome(暴力Trie)

    CF-557 E. Ann and Half-Palindrome(暴力Trie) 题目链接 题意 给定一个字符串,求第K个半回文子串. 半回文串:对于字符串SSS, $S_i == S_{n-i+1 ...

  2. A 暴力搜索 剪枝是关键

    Description 盖伦是个小学一年级的学生,在一次数学课的时候,老师给他们出了一个难题: 老师给了一个正整数 n,需要在不大于n的范围内选择三个正整数(可以是相同的),使它们三个的最小公倍数尽可 ...

  3. 13.6.3 暴力 PDF 口令破解程序

    假定有一个加密的PDF 文件,你忘记了口令,但记得它是一个英语单词.尝试 猜测遗忘的口令是很无聊的任务.作为替代,你可以写一个程序,尝试用所有可能的英语单词来解密这个PDF 文件,直到找到有效的口令. ...

  4. 【搜索】Playoff (dfs暴力枚举+剪枝)

    题目描述 The Minato Mirai Football Association hosts its annual championship as a single round-robin tou ...

  5. 1740 蜂巢迷宫(模拟,暴力,剪枝)

    有一个无限大的蜂巢迷宫,为了方便表示每一个六边形格子,现在把座标引入到这个迷宫中,如上图年示. 艾瑞特在这个迷宫中街,刚开始他在(0,0)的位置,按照下图所示的路线在这个迷宫中行走. 走了n步以后,他 ...

  6. 暴力递归到动态规划 05 (贴纸拼词)

    题目链接 1. 暴力递归(超时) public int minStickers(String[] stickers, String target) {int result = minSticker(s ...

  7. [CF/AT]各大网站网赛 体验部部长第一季度工作报告

    文章目录 CodeForces #712 (Div. 1)--1503 A. Balance the Bits B. 3-Coloring C. Travelling Salesman Problem ...

  8. 算法 64式 7、搜索算法整理_第1部分_1到15题

    1 算法思想 算法分类 搜索算法主要分为: 暴力搜索+剪枝,枚举,广度优先搜索,深度优先搜索,二分查找,哈希查找, A*算法,两边向中间逼近,从中间向两边扩散等 1.1枚举 枚举: 最直白的搜索方式, ...

  9. HDU 1560 DNA sequence(DNA序列)

    HDU 1560 DNA sequence(DNA序列) Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K  ...

最新文章

  1. [转][linux]简单的linux下的tcp/udp
  2. 里写注释 postman_没用过这些IDEA插件?怪不得写代码头疼
  3. 推荐系统与GNN的火花
  4. char类型和Unicode编码
  5. python增强运算符_Python学习【第3篇】:Python之运算符
  6. Eclipse 汉化方法
  7. sshpass-Linux命令之非交互SSH密码验证
  8. 高效好用视频加密软件的4个特点
  9. arcolinux使用i3wm窗口管理器
  10. 何凯明最新一作:Masked Autoencoders Are Scalable Vision Learners
  11. c语言随机数猜数游戏
  12. Ember copy array
  13. STM32标准库驱动蜂鸣器
  14. 请没有买房和买车的朋友一定认真的看一下
  15. js去掉url中的域名的方法
  16. 1.4版走迷宫小游戏
  17. uni-app快速上手顺序
  18. 区块链中的节点是什么意思?
  19. 如何安装配置eosjs并连接到EOS区块链
  20. 户外运动装备新品--云息智能定位胸牌

热门文章

  1. vb计算机清除菜单代码,用VB编写简单的程序来清空文档菜单 (转)
  2. 给本地图片添加水印(图片,文字)
  3. flutter 如何实现上下标效果
  4. 最新版苹果公司开发者账户申请
  5. python语言迷宫游戏_一个Python迷宫小游戏
  6. 小米手机安装Google框架
  7. C程序中各个段的含义
  8. 国内外AI绘画软件汇总
  9. MATLAB机器人机械臂运动学正逆解、动力学建模仿真与轨迹规划
  10. 关于联想小新16pro无网络问题_雪雪专享篇(安装网卡驱动篇)