HDU 1880

    map超空间了,那就排序加二分呗...

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <memory.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <iostream>
#include <sstream>

using namespace std;

char s[150];
char a[100000][21], b[100000][81];
int sa[100000], sb[100000];

bool sacmp(const int &x, const int &y) {
    return strcmp(a[x], a[y]) == -1;
}
bool sbcmp(const int &x, const int &y) {
    return strcmp(b[x], b[y]) == -1;
}

int afind(char *s, int k) {
    int l = 0, r = k - 1, m, t;
    while (l <= r) {
        m = (l + r) / 2;
        t = strcmp(s, a[sa[m]]);
        if (t == -1) r = m - 1;
        else if (t == 1) l = m + 1;
        else return sa[m];
    }
    return -1;
}
int bfind(char *s, int k) {
    int l = 0, r = k - 1, m, t;
    while (l <= r) {
        m = (l + r) / 2;
        t = strcmp(s, b[sb[m]]);
        if (t == -1) r = m - 1;
        else if (t == 1) l = m + 1;
        else return sb[m];
    }
    return -1;
}

int main() {
    int n, i, j, k;
    while (gets(s)) {
        k = 0;
        do {
            if (strcmp(s, "@END@") == 0) break;
            for (i = 1, j = 0; s[i] != ']'; i++, j++)
                a[k][j] = s[i];
            a[k][j] = '\0';
            for (i += 2, j = 0; s[i]; i++, j++)
                b[k][j] = s[i];
            b[k][j] = '\0';
            k++;
        } while (gets(s));
        for (i = 0; i < k; i++)
            sa[i] = sb[i] = i;
        sort(sa, sa + k, sacmp);
        sort(sb, sb + k, sbcmp);
        scanf("%d", &n);
        getchar();
        for (i = 0; i < n && gets(s); i++) {
            if (s[0] == '[') {
                for (j = 0; s[j+1] && s[j+1] != ']'; j++)
                    s[j] = s[j+1];-
                s[j] = '\0';
                j = afind(s, k);
                if (j == -1) puts("what?");
                else printf("%s\n", b[j]);
            } else {
                j = bfind(s, k);
                if (j == -1) puts("what?");
                else printf("%s\n", a[j]);
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值