poj 3295 Tautology && poj 1035 Spell checker 【字典树】

各种不顺,G++ %lf卡我那么多次,一个水BFS卡我好长时间以及那道不用字典树都可以过的SB题。。。日狗了。
poj 3295 Tautology

判断给定的WFF式子是否永真。

正着逆波兰想太简单会出bug,直接倒着跑一遍就搞定了。zz

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
#include <cstring>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <string>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 5 * 1e5 + 1;
const int MAXM = 1e5 + 1;
const int INF = 1e9 + 10;
const int MOD = 998244353;
char str[1100];
int len;
int p, q, r, s, t;
int V(char op) {
    if(op == 'p') return p;
    if(op == 'q') return q;
    if(op == 'r') return r;
    if(op == 's') return s;
    if(op == 't') return t;
}
int Solve(int a, int b, char op) {
    if(op == 'K') {
        return (a & b);
    }
    if(op == 'A') {
        return (a | b);
    }
    if(op == 'C') {
        return ((!a) | b);
    }
    if(op == 'E') {
        return a == b;
    }
}
int Count() {
    int Stack[1100]; int top = 0;
    for(int i = len - 1; i >= 0; i--) {
        if(str[i] == 'A' || str[i] == 'K' || str[i] == 'C' || str[i] == 'E') {
            Stack[top-1] = Solve(Stack[top], Stack[top-1], str[i]);
            top--;
        }
        else if(str[i] == 'N') {
            Stack[top] = !Stack[top];
        }
        else {
            Stack[++top] = V(str[i]);
        }
    }
    return Stack[top];
}
int main()
{
    while(scanf("%s", str), str[0] != '0') {
        len = strlen(str);
        bool flag = true;
        for(p = 0; p <= 1; p++) {
            for(q = 0; q <= 1; q++) {
                for(r = 0; r <= 1; r++) {
                    for(s = 0; s <= 1; s++) {
                        for(t = 0; t <= 1; t++) {
                            if(Count() == 0) {
                                flag = false; break;
                            }
                        }
                        if(!flag) break;
                    }
                    if(!flag) break;
                }
                if(!flag) break;
            }
            if(!flag) break;
        }
        if(!flag) {
            printf("not\n");
        }
        else {
            printf("tautology\n");
        }
    }
    return 0;
}

poj 1035 Spell checker

题意:给定n个模式串和m次查询,每次查询给定一个字符串str,先判断str是否出现过,没有的话输出所有可以通过删除一个字符、增加一个字符、替换一个字符得到str串的所有模式串,按输入顺序输出。

建好字典树,跑DFS就可以啦。MDZZ,暴力都可以过。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
#include <cstring>
#include <queue>
#include <map>
#include <set>
#include <string>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 5 * 1e5 + 1;
const int MAXM = 1e5 + 1;
const int INF = 1e9 + 10;
const int MOD = 998244353;
int next[MAXN][30], id[MAXN];
bool vis[MAXN];
int L, root;
int newnode() {
    for(int i = 0; i < 26; i++) {
        next[L][i] = -1;
    }
    id[L++] = -1;
    return L - 1;
}
void init() { L = 0; root = newnode(); }
void Insert(char *s, int p) {
    int u = root, v;
    for(int i = 0; s[i]; i++) {
        v = s[i] - 'a';
        if(next[u][v] == -1) {
            next[u][v] = newnode();
        }
        u = next[u][v];
    }
    id[u] = p;
}
vector<int> p;
void DFS(int u, int use, int pos, char *s, int op) {
    switch(op) {
        case 1: if(!s[pos] && use == 1) {
                    if(id[u] != -1 && !vis[id[u]]) {
                        vis[id[u]] = true;
                        p.push_back(id[u]);
                    }
                }
                else {
                    for(int i = 0; i < 26; i++) {
                        if(next[u][i] == -1) continue;
                        if(s[pos] == 'a' + i)
                            DFS(next[u][i], use, pos + 1, s, op);
                        if(use < 1)
                            DFS(next[u][i], use + 1, pos, s, op);
                    }
                }
                break;
        case 2: if(!s[pos]) {
                    if(use == 1 && id[u] != -1 && !vis[id[u]]) {
                        vis[id[u]] = true;
                        p.push_back(id[u]);
                    }
                }
                else {
                    for(int i = 0; i < 26; i++) {
                        if(next[u][i] == -1) continue;
                        if(s[pos] == 'a' + i)
                            DFS(next[u][i], use, pos + 1, s, op);
                        else if(use < 1)
                            DFS(next[u][i], use + 1, pos + 1, s, op);
                    }
                }
                break;
        case 3: if(!s[pos])  {
                    if(use == 1 && id[u] != -1 && !vis[id[u]]) {
                        vis[id[u]] = true;
                        p.push_back(id[u]);
                    }
                }
                else {
                    for(int i = 0; i < 26; i++) {
                        if(next[u][i] == -1) continue;
                        if(s[pos] == 'a' + i)
                            DFS(next[u][i], use, pos + 1, s, op);
                    }
                    if(use < 1) {
                        DFS(u, use + 1, pos + 1, s, op);
                    }
                }
    }
}
bool judge(char *s) {
    int u = root;
    for(int i = 0; s[i]; i++) {
        int v = s[i] - 'a';
        if(next[u][v] == -1) return false;
        u = next[u][v];
    }
    return id[u] != -1;
}
char str[MAXN][100], s[100];
int main()
{
    init(); int n = 1;
    while(scanf("%s", str[n]), strcmp(str[n], "#")) {
        Insert(str[n], n); vis[n] = false; n++;
    }
    while(scanf("%s", s), strcmp(s, "#")) {
        if(judge(s)) {
            printf("%s is correct\n", s);
        }
        else {
            p.clear(); CLR(vis, false);
            DFS(root, 0, 0, s, 1);
            DFS(root, 0, 0, s, 2);
            DFS(root, 0, 0, s, 3);
            printf("%s:", s);
            sort(p.begin(), p.end());
            for(int i = 0; i < p.size(); i++) {
                printf(" %s", str[p[i]]);
            }
            printf("\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值