[Swust OJ 648]--简单字典(数位dp)

题目链接:http://acm.swust.edu.cn/problem/0648/

 

Time limit(ms): 1000    Memory limit(kb): 65535
 
有这样一本字典,它每个单词一页,单词没有相同字母。 
就像这样: 
a 1 
b 2 


z 26 
ab 27 


az 51 
ba 52 
bc 53 



Description
多组测试数据,每行是一个串长最大为10由小写字母组成的单词。 
以EOF结束。
Input
输出这个单词在这本字典的第几页
Output
1
2
3
4
a
az
abc
aa
Sample Input
1
2
3
4
1
51
677
ERROR
Sample Output
 
 
 
解题思路:这道题我们把它看做一个26进制的数位dp就可以了,就查找当前数前面有多少个数就是了,
     值得注意的是这里可以有多个前导零0001,0003等(if (!fzero&&istrue&(1 << i)) continue;),
     当一但出现非零数字后,后面的数字就不能再出现零(istrue | (1 << i))
     关于数位dp不会的可以戳戳这里:http://www.cnblogs.com/zyxStar/p/4563830.html
代码如下:
 
 1 /*******************数位dp*************************/
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 int n, bit[11], judge[27], flag;
 7 char s[11];
 8 
 9 int dfs(int pos, int istrue, bool limit, bool fzero){
10     if (pos < 0) return 1;
11     int last = limit ? bit[pos] : 26;
12     int ret = 0;
13     for (int i = fzero ? 0 : 1; i <= last; i++){
14         //允许多个前导零
15         if (!fzero&&istrue&(1 << i)) continue;
16         ret += dfs(pos - 1, istrue | (1 << i), limit&&i == last, fzero&&!i);
17     }
18     return ret;
19 }
20 
21 int main(){
22     while (cin >> s){
23         n = strlen(s);
24         flag = 0;
25         memset(judge, 0, sizeof(judge));
26         for (int i = n; i >= 1; i--){
27             bit[n - i] = s[i - 1] - 'a' + 1;
28             if (!judge[bit[n - i]]) judge[bit[n - i]] = 1;
29             else {
30                 flag = 1;
31                 break;
32             }
33         }
34         if (flag) cout << "ERROR\n";
35         else cout << dfs(n - 1, 0, 1, 1) - 1 << endl;
36     }
37     return 0;
38 }
View Code

 

posted @ 2015-06-09 15:51  繁夜  阅读(273)  评论(0编辑  收藏  举报