您的位置:首页 > 其它

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

2015-06-09 15:51 274 查看
题目链接: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
代码如下:

/*******************数位dp*************************/
#include <iostream>
#include <cstring>
using namespace std;

int n, bit[11], judge[27], flag;
char s[11];

int dfs(int pos, int istrue, bool limit, bool fzero){
if (pos < 0) return 1;
int last = limit ? bit[pos] : 26;
int ret = 0;
for (int i = fzero ? 0 : 1; i <= last; i++){
//允许多个前导零
if (!fzero&&istrue&(1 << i)) continue;
ret += dfs(pos - 1, istrue | (1 << i), limit&&i == last, fzero&&!i);
}
return ret;
}

int main(){
while (cin >> s){
n = strlen(s);
flag = 0;
memset(judge, 0, sizeof(judge));
for (int i = n; i >= 1; i--){
bit[n - i] = s[i - 1] - 'a' + 1;
if (!judge[bit[n - i]]) judge[bit[n - i]] = 1;
else {
flag = 1;
break;
}
}
if (flag) cout << "ERROR\n";
else cout << dfs(n - 1, 0, 1, 1) - 1 << endl;
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: