GCPC 13 A Boggle 暴力,Trie剪枝
///
题意:字典中总共有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剪枝相关推荐
- CF-557 E. Ann and Half-Palindrome(暴力Trie)
CF-557 E. Ann and Half-Palindrome(暴力Trie) 题目链接 题意 给定一个字符串,求第K个半回文子串. 半回文串:对于字符串SSS, $S_i == S_{n-i+1 ...
- A 暴力搜索 剪枝是关键
Description 盖伦是个小学一年级的学生,在一次数学课的时候,老师给他们出了一个难题: 老师给了一个正整数 n,需要在不大于n的范围内选择三个正整数(可以是相同的),使它们三个的最小公倍数尽可 ...
- 13.6.3 暴力 PDF 口令破解程序
假定有一个加密的PDF 文件,你忘记了口令,但记得它是一个英语单词.尝试 猜测遗忘的口令是很无聊的任务.作为替代,你可以写一个程序,尝试用所有可能的英语单词来解密这个PDF 文件,直到找到有效的口令. ...
- 【搜索】Playoff (dfs暴力枚举+剪枝)
题目描述 The Minato Mirai Football Association hosts its annual championship as a single round-robin tou ...
- 1740 蜂巢迷宫(模拟,暴力,剪枝)
有一个无限大的蜂巢迷宫,为了方便表示每一个六边形格子,现在把座标引入到这个迷宫中,如上图年示. 艾瑞特在这个迷宫中街,刚开始他在(0,0)的位置,按照下图所示的路线在这个迷宫中行走. 走了n步以后,他 ...
- 暴力递归到动态规划 05 (贴纸拼词)
题目链接 1. 暴力递归(超时) public int minStickers(String[] stickers, String target) {int result = minSticker(s ...
- [CF/AT]各大网站网赛 体验部部长第一季度工作报告
文章目录 CodeForces #712 (Div. 1)--1503 A. Balance the Bits B. 3-Coloring C. Travelling Salesman Problem ...
- 算法 64式 7、搜索算法整理_第1部分_1到15题
1 算法思想 算法分类 搜索算法主要分为: 暴力搜索+剪枝,枚举,广度优先搜索,深度优先搜索,二分查找,哈希查找, A*算法,两边向中间逼近,从中间向两边扩散等 1.1枚举 枚举: 最直白的搜索方式, ...
- HDU 1560 DNA sequence(DNA序列)
HDU 1560 DNA sequence(DNA序列) Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K ...
最新文章
- [转][linux]简单的linux下的tcp/udp
- 里写注释 postman_没用过这些IDEA插件?怪不得写代码头疼
- 推荐系统与GNN的火花
- char类型和Unicode编码
- python增强运算符_Python学习【第3篇】:Python之运算符
- Eclipse 汉化方法
- sshpass-Linux命令之非交互SSH密码验证
- 高效好用视频加密软件的4个特点
- arcolinux使用i3wm窗口管理器
- 何凯明最新一作:Masked Autoencoders Are Scalable Vision Learners
- c语言随机数猜数游戏
- Ember copy array
- STM32标准库驱动蜂鸣器
- 请没有买房和买车的朋友一定认真的看一下
- js去掉url中的域名的方法
- 1.4版走迷宫小游戏
- uni-app快速上手顺序
- 区块链中的节点是什么意思?
- 如何安装配置eosjs并连接到EOS区块链
- 户外运动装备新品--云息智能定位胸牌