USACO-Section 1.2 Name That Number[...]

来源:互联网 发布:丝路英雄葱岭冒险数据 编辑:程序博客网 时间:2024/05/22 16:56

2017-05-29
题目大意:

26个字母对应到数字(除了Q和Z)如下。现输入一个数字N(有112位的十进制整数,对应于字母组合),且给出一个定义了所有合法字母组合(不超过5000个)的文件dict.txt,要求按字母递增的顺序输出所有符合给定数字的合法字母组合。2: A,B,C     5: J,K,L    8: T,U,V3: D,E,F     6: M,N,O    9: W,X,Y4: G,H,I     7: P,R,S

样例输入:

4734

对应于此输入,候选的字母组合为:

GPDG GPDH GPDI GPEG GPEH GPEI GPFG GPFH GPFI GRDG GRDH GRDIGREG GREH GREI GRFG GRFH GRFI GSDG GSDH GSDI GSEG GSEH GSEIGSFG GSFH GSFI HPDG HPDH HPDI HPEG HPEH HPEI HPFG HPFH HPFIHRDG HRDH HRDI HREG HREH HREI HRFG HRFH HRFI HSDG HSDH HSDIHSEG HSEH HSEI HSFG HSFH HSFI IPDG IPDH IPDI IPEG IPEH IPEIIPFG IPFH IPFI IRDG IRDH IRDI IREG IREH IREI IRFG IRFH IRFIISDG ISDH ISDI ISEG ISEH ISEI ISFG ISFH ISFI

但是根据dict.txt,合法的字母组合只有GREG。所以样例输出为:

GREG

题解:

首先,输入的数字N决定了可能的字母组合有3^N种之多,而合法的字母组合<5000。所以想到先根据字符与数字的对应关系将合法的字母组合集转换成对应的数字集,并将输入的数字先与该数字集进行匹配,若没有匹配则输出”NONE”,程序结束。若有匹配,则记录每次匹配的起点和终点(因为合法的组合集是按递增顺序排列好的,可能会有连续的记录满足条件),而不连续的匹配区间可能有多个,所以要遍历整个合法字母组合集。

思路如上所述-_-||再次吐槽自己的编程水平。。但目前我只想赶快往下刷题,所以个人对此只好先。。。

代码如下(看看就好):

/*ID: madara01PROG: namenumLANG: C++*/#include <iostream>#include <fstream>#include <string>#define cin fin#define cout fout#define MAX 5001using namespace std;int main(int argc, char **argv){    string tname;    string number;    string pre_ind[MAX];  //合法名字的数字编号数组    int i,j,nameNum = 0;    ofstream fout ("namenum.out");    ifstream fin ("namenum.in");    ifstream dic ("dict.txt");    //泪崩T_T不知道怎么把指针复位到文件开头。。    //所以,目前只好重新定义一个文件指针-_-||    ifstream res ("dict.txt");    for(i = 0; i<MAX; i++)    {        if(dic.eof())  break;        dic >> tname;        nameNum ++; //合法名字的总数        for(j = 0; j<tname.length(); j++)        {  //对应规则            if('A'<=tname[j] && tname[j]<='C')  pre_ind[i] = pre_ind[i] + "2";            else if('D'<=tname[j] && tname[j]<='F')  pre_ind[i] = pre_ind[i] + "3";            else if('G'<=tname[j] && tname[j]<='I')  pre_ind[i] = pre_ind[i] + "4";            else if('J'<=tname[j] && tname[j]<='L')  pre_ind[i] = pre_ind[i] + "5";            else if('M'<=tname[j] && tname[j]<='O')  pre_ind[i] = pre_ind[i] + "6";            else if('P'<=tname[j] && tname[j]<='S' && tname[j]!='Q')  pre_ind[i] = pre_ind[i] + "7";            else if('T'<=tname[j] && tname[j]<='V')  pre_ind[i] = pre_ind[i] + "8";            else if('W'<=tname[j] && tname[j]<='Y')  pre_ind[i] = pre_ind[i] + "9";            else pre_ind[i] = pre_ind[i] + "0";        }    }    nameNum --;    cin >> number;    j = 0;    int temp = 0;    int ac = 0;  //标识问题是否有解    while(j < nameNum)  //解区间可能不止一个,所以要循环遍历整个dict    {        while(pre_ind[j] != number && j < nameNum)  j++;  //j指向当前第一个符合条件的合法名字        if(j >= nameNum && ac == 0)  cout << "NONE" << endl;        else        {            ac = 1;            for(i = j; i < nameNum && pre_ind[i] == number; i++)  ;            while(temp < j)            {                res >> tname;                temp ++;            }            while(temp < i)            {                res >> tname;                cout << tname << endl;                temp ++;            }            j = i;        }    }    return 0;}
原创粉丝点击