题目链接: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
.
.
就像这样:
a 1
b 2
.
.
z 26
ab 27
.
.
az 51
ba 52
bc 53
.
.
Description
多组测试数据,每行是一个串长最大为10由小写字母组成的单词。
以EOF结束。
以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
代码如下:
/*******************数位dp*************************/
#include <iostream>
#include <cstring>
using namespace std; int n, bit[], judge[], flag;
char s[]; int dfs(int pos, int istrue, bool limit, bool fzero){
if (pos < ) return ;
int last = limit ? bit[pos] : ;
int ret = ;
for (int i = fzero ? : ; i <= last; i++){
//允许多个前导零
if (!fzero&&istrue&( << i)) continue;
ret += dfs(pos - , istrue | ( << i), limit&&i == last, fzero&&!i);
}
return ret;
} int main(){
while (cin >> s){
n = strlen(s);
flag = ;
memset(judge, , sizeof(judge));
for (int i = n; i >= ; i--){
bit[n - i] = s[i - ] - 'a' + ;
if (!judge[bit[n - i]]) judge[bit[n - i]] = ;
else {
flag = ;
break;
}
}
if (flag) cout << "ERROR\n";
else cout << dfs(n - , , , ) - << endl;
}
return ;
}