题目就是给出了一个矩阵,由大写字母构成,然后让你查找某些单词在矩阵中出现的位置
出现的方式可能有8种,从某个位置往北连续的字符串,往东北,东........八个方向的只要有满足的 就可以
最后输出位置和方向,然后往北的输出时为A,东北的是B,依次顺时针类推
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#define eps 1e-5
#define MAXN 1111
#define MAXM 222200
#define INF 1000000000
using namespace std;
int e, cnt, L, C, W;
char s[MAXN][MAXN];
bool vis[MAXN];
int ansx[MAXN], ansy[MAXN], len[MAXN];
int loc[MAXN];
int tx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, ty[8] = {0, 1, 1, 1, 0, -1, -1, -1};
char dic[] = "ABCDEFGH";
char tmp[MAXN];
struct Trie
{
int next[26];
int fail, id;
void init ()
{
memset(next, 0, sizeof(next));
fail = -1;
id = 0;
}
} trie[MAXM];
void make_trie (char *str, int id)
{
int i = 0, index, u = 0;
while(str[i])
{
index = str[i] - 'A';
if(!trie[u].next[index]) trie[u].next[index] = ++e;
u = trie[u].next[index];
i++;
}
trie[u].id = id;
}
int q[MAXM];
void make_ac_automation()
{
int i, j;
int h = 0, t = 0;
q[t++] = 0;
while(h < t)
{
int u = q[h++];
for(i = 0; i < 26; i++)
if(trie[u].next[i])
{
int v = trie[u].next[i];
for(j = trie[u].fail; j != -1; j = trie[j].fail)
if(trie[j].next[i])
{
trie[v].fail = trie[j].next[i];
break;
}
if(j == -1) trie[v].fail = 0;
q[t++] = v;
}
}
}
void match(int x, int y, int k)
{
int u = 0, index;
while(s[x][y])
{
index = s[x][y] - 'A';
while(!trie[u].next[index] && u != 0) u = trie[u].fail;
u = trie[u].next[index];
if(u == -1) u = 0;
int v = u;
while(v != 0 && trie[v].id != -1)
{
if(trie[v].id > 0 && !vis[trie[v].id])
{
cnt++;
vis[trie[v].id] = 1;
ansx[trie[v].id] = x - (len[trie[v].id] - 1) * tx[k];
ansy[trie[v].id] = y - (len[trie[v].id] - 1) * ty[k];
loc[trie[v].id] = k;
if(cnt == W) return;
}
trie[v].id = -1;
v = trie[v].fail;
}
x += tx[k], y += ty[k];
}
}
int main()
{
for(int i = 0; i < MAXM; i++) trie[i].init();
scanf("%d%d%d", &L, &C, &W);
for(int i = 1; i <= L; i++) scanf("%s", s[i] + 1);
for(int i = 1; i <= W; i++)
{
scanf("%s", tmp);
make_trie(tmp, i);
len[i] = strlen(tmp);
}
make_ac_automation();
for(int i = 1; i <= C; i++)
match(L, i, 0);//A
for(int i = 1; i <= L; i++)
match(i, 1, 1);//B
for(int i = 1; i <= C; i++)
match(L, i, 1);//B
for(int i = 1; i <= L; i++)
match(i, 1, 2);//C
for(int i = 1; i <= C; i++)
match(1, i, 3);//D
for(int i = 1; i <= L; i++)
match(i, 1, 3);
for(int i = 1; i <= C; i++)
match(1, i, 4);//E
for(int i = 1; i <= L; i++)
match(i, C, 5);//F
for(int i = 1; i <= C; i++)
match(1, i, 5);
for(int i = 1; i <= L; i++)
match(i, C, 6);//G
for(int i = 1; i <= C; i++)
match(L, i, 7);//H
for(int i = 1; i <= L; i++)
match(i, C, 7);
for(int i = 1; i <= W; i++)
if(vis[i]) printf("%d %d %c\n", ansx[i] - 1, ansy[i] - 1, dic[loc[i]]);
return 0;
}
分享到:
相关推荐
poj1007 AC代码 0MS过题写法 不过是个水题 哈哈哈哈
poj 3674 SuperAssassin 的AC代码
我的Poj里的一些AC代码
poj3586,推导题,可以推导出一个贪心的结论,具体看代码。
poj2342,树形dp,dp[i][0]表示i不参加party,其下属(包括非直接下属)能得到的最优值。dp[i][1]表示i参加的其下属和他能得到的最优值。
http://acm.pku.edu.cn/JudgeOnline/ acm的AC解题报告
一年多的ACM经历,做了这300多题,希望对大家有帮助!!
poj2343,规模比较小,只有50,搜索即可,具体看代码。
POJ 1328 java做!雷达问题!java版本!AC答案~
复杂度n^2 b
poj2628,判断需要锯掉多少长度才能使得桌子平衡,可以知道至少需要三根相同长度且是最长的桌腿。按桌腿长度排序,然后判断是否可以保持平衡(所有桌腿不同在圆心的一边即可)
poj1125原创AC代码,用的是folyd算法,求出所有点之间的最短路径,再以此求出每个点到其他点的最长路径。。。
poj2340,模拟题,使用两个优先队列模拟即可。
poj2605,简单推导题。分几种情况讨论即可。
poj2599,简单dfs可以过此题,按顺序搜到任意可行解即可。
北大poj AC源码1600个(C或C++)
1000 1003 1004 1005 1006 1008 1012 1028 1036 1045 1046 1047 1087 1163 1183 1207 1218 1247 1269 1298 1306 1316 1326 1331 1338 1401 1423 1450 1455 1477 1488 1503 1504 1517 1519 1528 1543 1547 1552 1555 ...
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
解决poj1006问题
用栈来解决。设置两个数组,其中一个是要求输入的数组a。另一个数组b用于保存含有相同的元素的序列。 先把数组的第一个值压入栈底,在看第二个数是不是和第一个数是相同的。如果相同则进栈,否则的话栈底元素出栈...