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;

}

/**/

你可能感兴趣的:(number)