1031: Hungar的得分问题(二)
时间限制: 1 Sec 内存限制: 64 MB提交: 15 解决: 10
[提交][状态][讨论版]
题目描述
距离正式选秀时间越来越近了,今天Hungar打算组织一场比赛!
于是他和其他4名队员组成了一支队伍,比赛就此开始,然而计分器似乎出了点问题,Hungar惊奇得发现,当第一次得分时,计分器显示的是4,第二次是7,第三次是44.....
Hungar马上发现,这些显示的数字只包含4和7,他突然想知道,给定一个这样的数字,它的排名是多少?
输入
第一行一个整数T(T <=100), 代表有T组数据.
对于每一组数据,包含一个整数n(1 <= n <= 10^9).
输出
n的排名.
样例输入
34777
样例输出
126
提示
输入数据保证合法(即n只包含4和7)
排名从小到大开始排.
例如排在第1的是4,排在第2的是7......
为数不多的仔细思考想出的题,刚开始只知道算可以求前面几次的次数sum(N:1~s.size-1,列在纸上可以构成杨辉三角),但是到n以为是个next_permutation,然后打表看了下数据比较大的情况下早过万了,用next估计超时,然后想半天找到了4和7出现的相对位置与本次序数关系——首先将4与7化为2进制的0与1,然后转换为十进制,再加上前面的sum,即可得到答案。似乎递推顺序并非按字典序...与next的顺序只有几组符合答案,纠结半天想碰碰运气结果AC了
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<queue> #include<set> #include<map> #include<sstream> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; int poww(int n) { int sum=1; for (int i=1; i<=n; i++) sum*=2; return sum; } int bi_to_dec(string s)// { int sum=0; for (int i=0; i<(int)s.size(); i++) { sum=sum*2+s[i]-'0'; } return sum; } void change(string &s)//转换为2进制 { for (int i=0; i<(int)s.size(); i++) { if(s[i]=='7') s[i]='1'; else if(s[i]=='4') s[i]='0'; } } int main (void) { string s; int t; cin>>t; getchar(); while (t--) { getline(cin,s); int len=(int)s.size(); int ans=poww(len)-1;//计算前n-1组的sum change(s); ans=ans+bi_to_dec(s);//加上本次的序数 cout<<ans<<endl; } return 0; }