USACO section1.2 Name That Number

直接暴力也可,用的二分搜索+枚举,文件输入的调试了很久,后来不知道怎么就对了。
二分的是写成求最小符合条件的下标;

/*
PROG: namenum
LANG: C++
*/
# include <cstdio>
# include <cstring>
# include <cstdlib>

# define N 5000 + 10
# define LEN 20

int len[N];
char s[N][LEN];

char tab[30];

void build(void)
{
    for (int i = 'A'; i < 'S'; ++i)
        tab[i - 'A'] = (i-'A') / 3 + 2 + '0';
    tab['S'-'A'] = '7';
    for (int i = 0; i < 7; ++i)
        tab[i + 'T'-'A'] = i / 3 + 8 + '0';
    tab['Q'-'A'] = tab['Z'-'A'] = '*';
}

int cmp(const void *xx, const void *yy)
{
    char *x = (char *)xx;
    char *y = (char *)yy;
    int lenx = strlen(x), leny = strlen(y);
    if (lenx == leny) return strcmp(x, y);
    return lenx - leny;
}

int sideBsearch(int x, int *v, int n)
{
    int low, high, mid;

    low = 0, high = n - 1;
    while (low < high)
    {
        mid = low + (high-low)/2;
        if (v[mid] >= x) high = mid;
        else low = mid + 1;
    }

    if (v[low] == x) return low;
    else return -1;
}

void mapToNum(char *name, char *s)
{
    int i;
    for (i = 0; name[i]; ++i)
        s[i] = tab[name[i]-'A'];
    s[i] = '\0';
}

int main()
{
    FILE *fdic = fopen("dict.txt", "r");
    FILE *fin  = fopen("namenum.in", "r");
    FILE *fout = fopen("namenum.out", "w");

    build();
    int n = 0;
    while (EOF != fscanf(fdic, "%s\n", s[n])) ++n;
    fclose(fdic);

    qsort(s, n, sizeof(s[0]), cmp);

    for (int i = 0; i < n; ++i)
        len[i] = strlen(s[i]);

    char id[LEN], buf[LEN];

    fscanf(fin, "%s", id), fclose(fin);

    int lenid = strlen(id), cnt = 0;
    int i = sideBsearch(lenid, len, n);
    if (i >= 0)    for (int j = i; len[j] == lenid; ++j)
    {
        mapToNum(s[j], buf);
        if (strcmp(buf, id) == 0) {fprintf(fout, "%s\n", s[j]); ++cnt;}
    }
    if (cnt == 0) fprintf(fout, "NONE\n");
    fclose(fout);

    return 0;
}

/**/

原文地址:https://www.cnblogs.com/JMDWQ/p/2595811.html