【题目大意】:给你一个字符串,里面的前一部分是一个数,后一部分是表示他的进制,问这个字符串可以表示成多少个数。
【解题思路】:表示某进制数下到第i位表示数的个数....dp[i]=sigema(dp[j])(j>=0 && j<i) 要加要满足能构成某进制数的条件。
条件有2个:1、首先它的前部分的数字必须小于进制数,2、除非它是一个数,否则第一个数位不能是0...(wa了..这里)
大环境1个:进制的首位不能是0;
【代码】:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
using namespace std;
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define linf 1LL<<60
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long
int len;
char s[50];
int cnt[50];
int cnt_num(int r){
int n;
n=len;
if (s[n-r]=='0') return 0;
cnt[0]=1;
for (int i=1; i<=n-r; i++){
cnt[i]=0;
int minn;
if (i-r<0) minn=0;
else minn=i-r;
for (int j=minn; j<i; j++){
if ((j+1<i || j==0 && n-r>1) && s[j]=='0') continue;
if (j+r==i) if (strncmp(s+j,s+n-r,r)>=0) continue;
cnt[i]+=cnt[j];
}
}
return cnt[n-r];
}
int main(){
int r,c;
while (1){
scanf("%s",s);
if (s[0]=='#') break;
len=strlen(s);
int ans=0;
for (int i=1; i<len; i++)
ans+=cnt_num(i);
if (ans>0)
printf ("The code %s can represent %d numbers.\n",s,ans);
else printf ("The code %s is invalid.\n",s);
}
return 0;
}