您的位置:首页 > 其它

2016 USP Try-outs Gym101064

2016-08-27 03:59 447 查看
link:http://codeforces.com/gym/101064

Gym 101064A. Renzo and the lost artifact

题意

给你一张大地图和一张小地图,大地图和小地图上面所表示的是某个地方的同一块区域,然后以大地图的左下角为原点建系,告诉你小地图的四个点的坐标,这四个点依次是小地图正面所示时的左下角沿逆时针方向的四个点。然后让你求某个坐标位置,大地图和小地图上表示的是同一个地方。

思路

这个题的关键是要读懂题目的意思,题目并没有说明地图如何放的,只是给出了坐标,所以情况不止一种,顺时针、转90度都有可能。为了避免罗列很多多种情况,于是搬出了“向量法”这种神奇的东东,然后成功将问题变成解方程,十分巧妙。

source

#include <bits/stdc++.h>
using namespace std;
double sqrsum(double x, double y) {
return x * x + y * y;
}
int main() {
double W, H, x[5], y[5];
cin >> H >> W;
for (int i = 1; i <= 4; i++) {
cin >> x[i] >> y[i];
}
double AB2 = sqrsum(x[2] - x[1], y[2] - y[1]), e1 = x[1] * (x[2] - x[1]) + y[1] * (y[2] - y[1]);
double AD2 = sqrsum(x[4] - x[1], y[4] - y[1]), e2 = x[1] * (x[4] - x[1]) + y[1] * (y[4] - y[1]);
double a1 = x[2] - x[1] - AB2 / W, b1 = y[2] - y[1], c1 = e1;
double a2 = x[4] - x[1], b2 = y[4] - y[1] - AD2 / H, c2 = e2;
double X = (c1 * b2 - c2 * b1) / (a1 * b2 - a2 * b1);
double Y = (c1 * a2 - c2 * a1) / (b1 * a2 - b2 * a1);
printf("%.10f %.10f\n", X, Y);
return 0;
}


Gym 101064E. A Word to Trump All

题意

给一些A类串和B类串,让你构造出最短的包含所有A类串但不包含任何B类串的字符串出来

思路

包含和不包含都可以转化成模式匹配问题,先用A、B类串构造ac自动机,然后从空串开始bfs,假设在状态s的后面增加一个字符c,到了状态q,那么应该沿着q的fail链,统计是否匹配到A,B类串的情况。注意需要将A,B类串的匹配情况保存进状态的一部分来判重。

source

#include <bits/stdc++.h>
using namespace std;
const int SZ = 10;
const int TOTAL = 333;
int n, m;
struct ACAutomaton {
struct Node {
int nxt[SZ], state, fail;
};
Node tree[TOTAL];
int type[TOTAL], total;
int id(char ch) {
return ch - 'a';
}
void insert(char s[], int c) {
int cur = 0;
for (int i = 0; s[i]; i++) {
int ch = id(s[i]);
if (!tree[cur].nxt[ch]) tree[cur].nxt[ch] = total++;
cur = tree[cur].nxt[ch];
}
tree[cur].state = 1;
type[cur] = c;
}
void build() {
queue<int> que;
for (int i = 0; i < SZ; i++) {
if (tree[0].nxt[i]) que.push(tree[0].nxt[i]);
}
while (!que.empty()) {
int cur = que.front();
que.pop();
for (int i = 0; i < SZ; i++) {
int nxt = tree[cur].nxt[i];
if (nxt) {
int last = tree[cur].fail;
while (last && !tree[last].nxt[i]) last = tree[last].fail;
tree[nxt].fail = tree[last].nxt[i];
que.push(nxt);
}
}
}
}
struct BFSNode {
int last, cur, vis;
char ch;
BFSNode() {}
BFSNode(int last, char ch, int cur, int vis) {
this->last = last;
this->ch = ch;
this->cur = cur;
this->vis = vis;
}
};
bool vis[TOTAL][1 << 15];
int check(int cur) {
int ans = 0;
while (cur) {
if (type[cur]) {
if (type[cur] > n) return -1;
ans |= 1 << (type[cur] - 1);
}
cur = tree[cur].fail;
}
return ans;
}
vector<int> ans;
BFSNode que[TOTAL * (1 << 15) + 10];
int match[TOTAL][10];
void dfs(int cur) {
if (cur == 0) return;
ans.push_back(que[cur].ch);
dfs(que[cur].last);
}
int chk[TOTAL];
void bfs() {
for (int i = 0; i < total; i++) chk[i] = check(i);
for (int i = 0; i < total; i++) {
for (int j = 0; j < SZ; j++) {
int nxt = i;
while (nxt && !tree[nxt].nxt[j]) nxt = tree[nxt].fail;
match[i][j] = tree[nxt].nxt[j];
}
}
int head = 0, tail = 0;
que[tail++] = BFSNode(-1, 0, 0, 0);
while (head < tail) {
BFSNode cur = que[head++];
if (cur.vis == (1 << n) - 1) {
dfs(head - 1);
break;
}
for (int i = 0; i < SZ; i++) {
int nxt = match[cur.cur][i];
int res = chk[nxt];
if (res != -1) {
int newvis;
if (vis[nxt][newvis = cur.vis | res]) continue;
vis[nxt][newvis] = 1;
que[tail++] = BFSNode(head - 1, i + 'a', nxt, newvis);
}
}
}
if (ans.size()) {
for (int i = ans.size() - 1; i >= 0; i--) putchar(ans[i]);
puts("\n");
}
else puts("-");
}
} ac;
char s[333];

int main() {
cin >> n >> m;
ac.total = 1;
for (int i = 1; i <= n; i++) {
scanf("%s", s);
ac.insert(s, i);
}
for (int i = 1; i <= m; i++) {
scanf("%s", s);
ac.insert(s, n + i);
}
ac.build();
ac.bfs();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gym 向量法 ac自动机