首页 > 试题广场 >

幸运数字

[编程题]幸运数字
  • 热度指数:2872 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

小雅同学认为6,8是她的幸运数字,而其他数字均不是,一个幸运数是指在十进制表示下只含有幸运数字的数。给定你一个区间(a,b)a和b之间(其中包括a和b幸)运数的个数。


输入描述:
输入两个整数a和b,a的取值范围在1和1000000000之间(其中包括1和1000000000),b的取值范围在a和1000000000之间(其中包括a和1000000000)。


输出描述:
返回a和b之间的幸运数个数,如果入参不合法,请输出-1
示例1

输入

1 10

输出

2

说明

6,8,6666,88888,6668888,68686688均为幸运数字,当a=1,b=10函数返回值为2。
//用字符串超时超内存,int取余就好.
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            int start=sc.nextInt();
            int end=sc.nextInt();
            if(start<1||end>1000000000||start>end){
                System.out.println(-1);
                return;
            }
            int count=0;
            for(int i=start;i<=end;i++){
                int temp=i;
                while(temp>10&&(temp%10==6||temp%10==8)){
                    temp=temp/10;
                }
                if(temp==6||temp==8){
                    count++;
                }
            }
            System.out.println(count);
        }
    }
}


发表于 2019-01-15 01:46:35 回复(0)
/**
 * f[i][j]表示长度为i, 以j为开头的幸运数字个数
 * 如f[1][0] = 0, f[1][6] = 1, f[1][8] = 1
 * 转移方程如下:
 * f[i][0] = f[i-1][6] + f[i-1][8] + f[i-1][0];
 * f[i][6] = f[i-1][6] + f[i-1][8];
 * f[i][8] = f[i-1][6] + f[i-1][8];
 *
 * 时间复杂度为数字的位数log(10, n)
 */
class Solution {

    private static int[][] f = new int[11][10];

    static {
        f[1][6] = 1;
        f[1][8] = 1;
        for (int i = 2; i <= 10; i++) {
            f[i][0] = f[i-1][6] + f[i-1][8] + f[i-1][0];
            f[i][6] = f[i-1][6] + f[i-1][8];
            f[i][8] = f[i-1][6] + f[i-1][8];
        }
    }

    public int numOfLuckNumber(int n) {
        if (n <= 0) return 0;
        int[] b = new int[10];
        int m = 0;
        while (n > 0) {
            b[m++] = n % 10;
            n /= 10;
        }

        int ans = f[m][0];
        boolean tag = true;
        for (int i = m-1; i >= 0; i--) {
            for (int j = 1; j < b[i]; j++) {
                ans += f[i+1][j];
            }
            if (b[i] != 8 && b[i] != 6) {
                tag = false;
                break;
            }
        }
        if (tag) ans++;
        return ans;
    }
}

发表于 2022-08-22 21:15:28 回复(0)
#这个代码比较乱,但可以顺序输出结果。已AC
while True:
    try:
        a, b = map(int, input().split())
        if 1 <= a <= 1000000000 and a <= b <= 1000000000:
            res = [0]         #保存幸运数个数
            temp = list(str(a))
                 
            #找出范围内最小的幸运数
            for i in range(len(temp)):
                if temp[i] == '6' or temp[i] == '8':
                    continue
                if temp[i] == '9':
                    temp[i] = '6'
                    for j in range(i - 1, -1, -1):
                        if temp[j] == '6':
                            temp[j] = '8'
                            break
                    else:
                        temp.insert(0, '6')
                elif temp[i] == '7':
                    temp[i] = '8'
                else:
                    temp[i] = '6'
                temp[i + 1: len(temp)] = ['6'] * (len(temp) - (i + 1))
                break
           #此时temp保存着最小的幸运数十进制位数的数组            

            #递归查找结果函数
            def pathThrought(index):
                if index == len(temp) - 1:
                    nowNum = int(''.join(temp))     #此时得到一个幸运数
                    if nowNum <= b:
                        res[0] += 1                 #可在此处输出nowNum
                        if temp[-1] == '6' and nowNum + 2 <= b:
                            res[0] += 1             #nowNum + 2也为一个幸运数
                else:
                    pathThrought(index + 1) #进来的时候temp[index]为6,递归一次
                    temp[index] = '8'       
                    pathThrought(index + 1) #置为8再递归一次
                    temp[index] = '6'       #赋值回去6
            
            #调用递归的过程
            while int(''.join(temp)) <= b:
                pathThrought(len(temp) - 1)
                for i in range(len(temp) - 2, -1, -1): #从末尾位数开始
                    if temp[i] == '8':       #当前位数不能再增大,跳过
                        continue
                    temp[i] = '8'            #本为6,增大为8,然后将右边位数置为6
                    temp[i + 1:] = ['6'] * (len(temp) - i - 1)
                    if int(''.join(temp)) > b:
                        break
                    pathThrought(i + 1)        #进行递归
                
                temp = ['6'] * (len(temp) + 1) #当前位数循环结束,增加位数继续
            print(res[0])

        else:   # a > b的情况
            print(-1)
    except ValueError:  #参数不正确的情况
        print(-1)
    except Exception:
        break

编辑于 2019-03-27 23:43:08 回复(0)
#include <bits/stdc++.h>

using namespace std;

bool F(int n){     while(n){         int t = n%10;         if(t!=8 && t!=6)             return false;         n /= 10;     }     return true;
}

int main()
{     int a,b,cnt=0;     cin>>a>>b;     if(a<1 || a>1000000000 || b<1 || b>1000000000 || a>b)          cout<<-1<<endl;     else{         for(int i=a;i<=b;i++)             if(F(i))                 cnt++;         cout<<cnt<<endl;     }     return 0;
}

发表于 2019-02-22 03:14:12 回复(0)
其实我的思路很简单,都不用用到二叉树,直接进行判断,由于范围都在整数范围内,所以直接判断输入的每一位是否是6或者8即可,然后遍历从a到b的每一个数都进行判断即可,可能复杂度稍微高,但是实现非常简单且在时间范围内hhh
#include<iostream>
using namespace std;
bool judge(int n){
    while(n>0){
        int temp=n%10;
        if(n%10!=8&&n%10!=6)
            return 0;
        n/=10;
    }
    return 1;
}
int main(){
    int a,b;//1-1000000000都还是属于2^31-1的范围内,所以用整数就OK
    cin>>a>>b;
    if(!((a<=1000000000&&a>=1)&&(b<=1000000000&&b>=1)))
       cout<<-1;
    else{
        int count=0;
        for(int i=a;i<=b;i++){
            if(judge(i))
                count++;
        }
        cout<<count<<endl;
    }
}

发表于 2019-02-11 20:48:40 回复(2)
l = []
def ran(a,x):
    if a == 0:
        l.append(int(x))
        return
    ran(a-1,x+'6')
    ran(a-1,x+'8')
lucky = '68'
for i in range(1,10):
    ran(i,'')
a,b = map(int,input().split())
if a>=1 and a<=1000000000 and b>=1 and b<=1000000000:
    index1,index2 = -1,-1
    for i in range(len(l)):
        if l[i]>=a:
            index1 = i
            break
    for i in range(len(l)):
        if l[i]>=b:
            index2 = i
            break
    if index1==-1:
        print(0)
    elif index2 == -1:
        print(len(l)-index1)
    else:
        print(index2-index1)
else:
    print(-1)

发表于 2019-01-24 11:51:37 回复(0)
使用二叉树。
如果当前数大于b的值,就直接返回到上一级的node。
否则继续往数字尾部加6和8,然后检查数字符不符合条件。

import java.util.Scanner;

public class Main {

    public static int count = 0;

    public static void Btree(int pre, int a, int b) {
        if (pre > b) {
            return;
        } else {
            if (pre >= a && pre <= b) {
                count++;
            }
            Btree(pre * 10 + 6, a, b);
            Btree(pre * 10 + 8, a, b);
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        Btree(0, a, b);
        System.out.println(count);
        sc.close();
    }

}
发表于 2019-01-23 10:19:07 回复(0)
1.求a到b区间的幸运数,那么只要分别求出0到a和0到b的幸运数然后作差就可以了
2.因为范围是 0到1e10,所以幸运数的数量应该是2e10
3.幸运数可以通过画一颗二叉树发现规律,层次遍历是这样的,6,8,66,68,86,88,666,668,686,688,866,868,886,888....可以发现对于每个节点,左子树是×10+6,右子树是×10+8,然后用数组模拟一个队列,把所有的值存进去,然后刚好就是从小到大,然后用a和b表示刚好大于或者等于的一个幸运数,然后做差就行
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5+5;
#define MAX 1000000000
int lucky[maxn];
int top;
void init();
int main()
{
    init();
    int a,b,ansa=0,ansb=0;
    cin>>a>>b;
    for(int i=0;i<top;++i)
    {
        if(a<lucky[i])
        {
            ansa=i;
            break;
        }
    }
    for(int i=0;i<top;++i)
    {
        if(b<lucky[i])
        {
            ansb=i;
            break;
        }
    }
    //cout<
    if(ansb-ansa>0)
    {
        cout<<ansb-ansa<<endl;
    }else 
    {
        cout<<"-1"<<endl;
    }
    return 0;
}
void init()
{
    int i=0;
    top=2;
    lucky[0]=6;
    lucky[1]=8;
    while(1)
    {
        if(i>512) break;
        lucky[top++]=lucky[i]*10+6;
        lucky[top++]=lucky[i]*10+8;
        i++;
    }
}



发表于 2019-01-18 18:12:32 回复(0)
//DFS + string 写法, 思路相当于是枚举,枚举幸运数的过程中,记录可行的(当然不是全部枚举)
//分别从6 和 8 开始每次从尾部开始分别 +“6” 或者 +“8”
#include <iostream>
#include <string.h>
using namespace std;
int ans = 0;    //全局的,所有在程序内的对ans的操作都会被记录下来
string a = "";      //上下界均为string类型的,操作的时候也好操作,比较的时候需要注意下
string b = "";

void DFS(string temp_str)
{
    if (temp_str.length() > b.length() || (temp_str.length() == b.length() && temp_str.compare(b) > 0))
    return;    //出口条件为 当前的temp_str大于上界b的时候,就要跳出
    else
    {
        if (temp_str.length() > a.length() || (temp_str.length() == a.length() && temp_str.compare(a) >= 0))
        ans++;   //满足上面的非出口条件就一定小于上界,然后满足大于等于下界,这个幸运数就可计
        DFS(temp_str + "6");       //从尾部+“6”进行递归
        DFS(temp_str + "8");      //从尾部+“8”进行递归
    }
}

int main()
{
    cin >> a >> b;
    if (a.length() > b.length() || a.compare(b) >= 0)  //输入异常情况
    cout << "-1";
    else
    {
        DFS("6");      //起始为“6”的递归
        DFS("8");      //起始为“8”的递归
        cout << ans;     //最后输出结果
    }
    return 0;
} 

编辑于 2019-02-17 20:57:34 回复(0)
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int main()
{
    string n,m;
    cin>>n>>m;
    int o=n.size(),o2=m.size();
    int s=0,u=pow(2,o+1);
    for (int i=o+1;i<o2;i++)
    {
        s+=u;
        u*=2;
    }
    u=1;
    for (int i=0;i<o;i++)
    {
    	if (n[i]<'6')
    	{
    		u=pow(2,o-i);
    		break;
		}
		if (n[i]>'8')
		{
			u=0;
			break;
		}
	}
	s+=u;
	u=1;
    for (int i=0;i<o;i++)
    {
    	if (m[i]>'8')
    	{
    		u=pow(2,o-i);
    		break;
		}
		if (m[i]<'6')
		{
			u=0;
			break;
		}
	}
	s+=u;
    cout<<s;
    return 0;
}
由于长度比左边界大又比右边界小大所有幸运数字都可以,然后我们只需要计算与左右边界一样长的个数,2个相加,应用数学方法解题
发表于 2020-10-06 11:52:09 回复(0)
#include<iostream>
#include<string>
bool isFortune(long long n)
{
    while(n>0)
    {
        if(n%10!=6&&n%10!=8)
        {
            return false;
            break;
        }
        n/=10;
    }
    return true;
}
int main()
{
    long long a,b;
    while(std::cin>>a>>b)
    {
        long long count=0;
        for(long long i=a;i<=b;i++)
        {
            if(isFortune(i))count++;
        }
        std::cout<<count<<std::endl;
    }
    return 0;
}
发表于 2020-09-12 14:53:51 回复(0)
a, b = list(map(int, input().split()))
if a < 1 or a > 1e+9 or b < a or b > 1e+9: print(-1)
else:
    sa, sb = "", ""
    while a > 0:
        a, c = a // 10, a % 10
        if c == 6 or c == 8: sa += str(int(c == 8))
        else:
            sa = '0' * len(sa) + str(int(c == 7))
            if c == 9: a += 1
    while b > 0:
        b, c = b // 10, b % 10
        if c == 6 or c == 8: sb += str(int(c == 8))
        else:
            sb = '1' * len(sb) + (str(int(c != 7)) if b > 0 else (str(int(c == 9)) if c > 6 else ''))
            if b > 0 and c < 6: b -= 1
    print(int(sb[:: -1], 2) - int(sa[:: -1], 2) + 1 + 2 ** len(sb) - 2 ** len(sa))

编辑于 2020-07-12 16:21:22 回复(0)
/**
 * 算法思想:
 *      幸运数字与定长二级制数对应(6->0, 8->1)
 *      所以求出a,b的长度区间[min, max]
 *          记区间内的数字i 2^i 为对应长度的幸运数字的个数
 *      然后扣除min中小于a的和max中大于b的
 * 运行时间:2ms
 * 占用内存:376k
*/

#include <iostream>

using namespace std;

class Solution {
private:
    int out;

public:
    Solution(const int& a, const int& b);
    ~Solution();
    friend ostream& operator<<(ostream& os, const Solution& s);

    // 求出数字的长度
    static int length(int n);

    // 将数字(二进制)转化为对应的幸运数字(0->6, 1->8)
    static int number2lucky(int n, int length);

    // 长度为length中的额幸运数字小于 n 的有多少个
    static int lessNumber(int n, int length);

    // 长度为length中的额幸运数字小于等于 n 的有多少个
    static int lessEqualNumber(int n, int length);
};

Solution::Solution(const int& a, const int& b)
{
    if (a > b) {
        out = -1;
        return;
    }
    int min = this->length(a);
    int max = this->length(b);
    this->out = 0;
    for(int i = min; i < max; ++i) {
        this->out += long(1 << i);
    }

    // 扣除min中不符合规则的
    this->out -= Solution::lessNumber(a, min);
    this->out += Solution::lessEqualNumber(b, max);
}

Solution::~Solution()
{
}

int Solution::length(int n)
{
    int ret = 0;
    while (n != 0) {
        ret++;
        n /= 10;
    }
    return ret;
}

int Solution::number2lucky(int n, int length) 
{
    int ret = 0;
    for (int i = 0, e = length; i < e; i++) {
        ret *= 10;
        if ((1<<i) & n == 0) {
            ret += 6;
        } else {
            ret += 8;
        }
    }
    
    return ret;
}

int Solution::lessNumber(int n, int length) {
    int ret = 0;
    for(int i = 0, end = ((1 << (length+1)) - 1); i < end; i++) {
        int tmp = Solution::number2lucky(i, length);
        if(tmp < n) {
            ret++;
        } else {
            break;
        }
    }
    return ret;
}
int Solution::lessEqualNumber(int n, int length) {
    int ret = 0;
    for(int i = 0, end = ((1 << (length+1)) - 1); i < end; i++) {
        int tmp = Solution::number2lucky(i, length);
        if(tmp <= n) {
            ret++;
        } else {
            break;
        }
    }
    return ret;
}

ostream& operator<<(ostream& os, const Solution& s)
{
    os << s.out;
    return os;
}

int main(int argc, char* argv[])
{
    int a, b;
    cin >> a >> b;
    Solution s(a, b);

    cout << s << endl;
    return 0;
}

发表于 2020-07-10 22:58:29 回复(0)
//dfs算法
#include <iostream>

using namespace std;

int result = 0;

void dfs(int x, int a, int b){


    if(x>b){
        return;
    }
    if(x>=a && x<=b){
        result++; //这里不要return
    }

    dfs(10*x+6, a, b);
    dfs(10*x+8, a, b);

    return;
}

int main(){

    int a, b;
    while(cin >> a >> b){

        dfs(0, a, b);

        cout << result << endl;
    }
    return 0;
}
发表于 2020-03-16 11:22:17 回复(0)
package com.hhdd.offer.wanglong;

import java.util.Scanner;

public class LuckyNum {


    public static boolean isLuckNum(int num) {
        if (num == 0) {
            return false;
        }
        while (num != 0) {
            if ((num % 10) != 6 && (num % 10) != 8) {
                return false;
            }
            num /= 10;
        }
        return true;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        int b = scanner.nextInt();
        int count = 0;
        for(int i = a;i<=b;i++){
            if(isLuckNum(i)){
                count++;
            }
        }
        System.out.println(count);
    }

}

发表于 2019-09-01 22:25:08 回复(0)
#include <iostream>
using namespace std;
int fun(int a,int b);
int main()
{
int a,b,c;
cin>>a>>b;
c=fun(a,b);
cout<<c;

}
int fun(int a,int b)
{
int temp,count=0;
for(int i=a;i<=b;i++)
{
temp=i;
while(temp>10)
{
if(temp%10==6||temp%10==8) temp=temp/10;
else break;
}
if(temp==6||temp==8) count++;

}
if(a>b) return -1;
else return count;
}
编辑于 2019-08-20 11:30:32 回复(0)
//复杂度只与b的位数有关系,以b=9977为例,可以先算出1000以内符合要求的个数,
//对于[1001,9977]的个数,可以遍历9977的每一位如果在<6范围,K * = 0,
//如果在([6,8) K *=1,如果在 [8, )范围K*=2。

 int getKind(int num){
    string str = to_string(num);
    int d = str.size() - 1;
    
    int ans = 0;
    for(int i=1;i<=d;++i){
        ans += (1<<i);
    }
    
    int k = 1;
    for(int i=0;i<str.size();++i){
        if(str[i] - '0' <6){
            k *= 0;
        }else if (str[i] - '0'>=6&&str[i] - '0'<8){
            k *= 1;
        }else if (str[i] - '0' >=8){
            k *= 2;
        }
    }
    ans += k;
    return ans;
}

编辑于 2019-06-04 14:33:02 回复(0)

import java.util.*;

public class Main{
static void f(int n,int cnt,char[] s,ArrayList ss){
if(cnt==n){
s[cnt]='\0';
ss.add(new String(s));
return ;
}else{
s[cnt]='6';
f(n,cnt+1,s,ss);
s[cnt]='8';
f(n,cnt+1,s,ss);
}
}
public static void main(String[] args){
ArrayList ss=new ArrayList();
for(int i=1;i<=9;i++){
char[] s=new char[i+1];
f(i,0,s,ss);
}
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int m=input.nextInt();
int count=0;
for(int i=0;i<ss.size();i++){
int xx=Integer.parseInt(ss.get(i).trim());
if(xx>=n&&xx<=m) count++;
}
System.out.println(count);
input.close();
}
}

先用递归把所有的结果储存起来,然后再根据输入的时候查找基数

发表于 2019-05-31 15:01:49 回复(0)
发表于 2019-04-19 18:23:31 回复(0)
//回答提交的代码格式总是出问题...难道是个bug?
import java.util.*;
public class Main{
 public static int help(Long l){  int len = l.toString().length();  int res = (int) (Math.pow(2, len)-2);  for (int i = 0; i < l.toString().length(); i++) {  int t = l.toString().charAt(i) - '0';  len--;  if (t > 8)  return res+(int)(Math.pow(2, len+1));  else if (t < 6)  return res;  else if (t == 8)  res=+(int) Math.pow(2, len);  else if (t == 6)   continue;  else return res+(int)Math.pow(2, len);  }  return res;
   }
    public static void main(String[] args){
    Scanner sc=new Scanner(System.in);
    Long a=sc.nextLong();
    Long b=sc.nextLong();
    System.out.print(help(b)-help(a));
    }
} 

编辑于 2019-03-21 17:04:25 回复(0)

问题信息

上传者:小小
难度:
25条回答 6290浏览

热门推荐

通过挑战的用户

查看代码