【递归与递推】编码
【递归与递推】编码
题目描述
编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数宇。
字母表中共有26个字母{a,b,…,z},这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。
例如:
a→1 b→2 z→26 ab→27 ac→28
你的任务就是对于所给的单词,求出它的编码。
字母表中共有26个字母{a,b,…,z},这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。
例如:
a→1 b→2 z→26 ab→27 ac→28
你的任务就是对于所给的单词,求出它的编码。
输入
仅一行,被编码的单词。
输出
仅一行,对应的编码。如果单词不在字母表中,输出0。
样例输入
ab
样例输出
27
分析:先检查单词是否符合要求;
统计1,2...len-1的个数分别为C(26,1)+C(26,2)...+C(26,len-1),到当前长度暴搜即可;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #include <ext/rope> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define vi vector<int> #define pii pair<int,int> #define mod 1000000007 #define inf 0x3f3f3f3f #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) const int maxn=10; const int dis[][2]={0,1,-1,0,0,-1,1,0}; using namespace std; using namespace __gnu_cxx; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} int n,m,len; string a,b; ll cnt; ll work(int p) { ll ans=1; p=max(p,26-p); for(int i=26;i>=p+1;i--)ans*=i; for(int i=1;i<=26-p;i++)ans/=i; return ans; } bool check(string p) { if(len>6)return false; else { string q=p; sort(q.begin(),q.end()); if(q!=p||unique(q.begin(),q.end())!=q.end())return false; return true; } } void dfs(string p,char x,int now) { if(now==len) { cnt++; if(p==a)exit(0*printf("%lld\n",cnt)); return; } for(char q=x+1;q<='z';q++)dfs(p+q,q,now+1); } int main() { int i,j,k,t; cin>>a; len=a.length(); if(check(a)==false)exit(0*puts("0")); for(i=1;i<=len-1;i++)cnt+=work(i); dfs("a",'a',1); printf("%lld\n",cnt); //system("pause"); return 0; }