问题描述
小W在3月7日这天失恋了,伤心的他开始无比讨厌3和7这两个数字,于是他创造了W计数法。W计数法在十进制的基础上去掉了所有含有数字3和数字7的数,例如2的下一个数是4,29的下一个数是40。小W想知道在这种计数法下X到Y之间有多少个数。
输入格式
一行两个整数表示X、Y,保证1<=X<=Y<=10^9,保证X和Y中不含数字3和数字7。
输出格式
一行一个整数表示X到Y之间有多少个数。
样例输入
10 100
样例输出
57
数据规模和约定
对于100%的数据,1<=X<=Y<=10^9。
此题附赠各种进制转换学习链接:进位制数及其相互转换
由于题目的数据范围达到了10^9,通过采取暴力枚举,把x和y之间的数一个个枚举出来,然后判断这个数是否符合,符合就自增1,这种方法是会超时的,只能拿到80分。
此种方法的AC代码:
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//采取二进制的思想
int x,y;
bool check(int x)
{
while(x)
{
if(x%10==3||x%10==7) return false;
x/=10;
}
return true;
}
int main(int argc, char** argv) {
cin>>x>>y;
int ans=0;
for(int i=x;i<=y;i++)
{
if(check(i)==true) ans++;
}
cout<<ans;
return 0;
}
正确的思路:
所谓的W计数法就是八进制数。在W计数法中,有0,1,2,4,5,6,8,9等八个数码,规则同样“逢八进一”,只不过W计数法中的“8”相当于十进制数中的“6”,W计数法中的“9”相当于十进制数中的“7”。若给出一个十进制数,要转换为W计数法中的数,则十进制的4、5、6应分别转换成3、4、5,8和9要转换为6和7。也就是说,将十进制整数转换成W计数法表示的八进制数时,每位的数字转换为一个数字,若数字超过了7,则减去2;若数字在4~6之间,则减去1;若数字为0~2,则保持不变。W计数法中不存在3和7。
按上面的方法将十进制数X写成W计数法表示的八进制数后,再将这个八进制数转换成十进制数,就知道W计数法中,X是第几个数。同样,将十进制数Y写成W计数法表示的八进制数后,再将这个八进制数转换成十进制数,就知道W计数法中,Y是第几个数。这样就知道X到Y之间有多少个数了。
AC代码:
#include <iostream>
#include <stdio.h>
using namespace std;
//采取十进制转八进制,然后再把八进制转换成十进制
//将10进制整数n转换为w计数法对应的八进制数,并保存到字符串s中
void de1(int n,char s[])
{
int i,j,k=0;
int a[13];
while(n)
{
a[k]=n%10;
if(a[k]>=7) a[k]-=2;
else if(a[k]>=3) a[k]--;
n/=10;
k++;
}
for(i=k-1,j=0;i>=0;i--,j++)
{
s[j]=a[i]+'0';
}
s[j]='\0';//结尾标志
}
// 将s中保存的8进制数转换为10进制数并返回
int de2(char s[])
{
int i,sum=0;
for(i=0;s[i]!='\0';i++)
{
sum=sum*8+s[i]-'0';
}
return sum;
}
int main(int argc, char** argv) {
int x,y;
cin>>x>>y;
char s[15];
de1(x,s);
x=de2(s);
de1(y,s);
y=de2(s);
cout<<y-x+1;//统计x~y之间有多少个数
return 0;
}