程序设计:查表法——报数游戏

查表法:建立大型数组,以空间换时间;
题目:

甲乙两人玩一个游戏,游戏规则为从1开始轮流报数,但如果下一个报的数的十进制表示中含有数字9,或者十进制表示中含有数字9的数的所有倍数都必须跳过否则会输掉游戏。 即两人从1开始轮流交替报数,报数过程中任何一个十进制中含有数字9的数、它的所有倍数都不能报出来。例如,甲同学报了8,由于9不能报,乙同学下一个需要报10;如果甲同学报了17,则由于18 = 9*2, 19中含有数字9,都不能报出,乙同学下一个需要报20。 请你帮助乙同学尽快找出要报出的数字。

输入和输出

输入:第1行,一个正整数T,表示询问的次数。接下来T行,每行一个正整数x,表示甲同学这一次报出的数字。
输出:共T行,每行一个整数,如果甲同学这次报出的数是不能报出的,输出-1,否则输出乙同学这次该报出的数是多少。

提示

30%的数据: T ≤ 10, x ≤ 100。
70%的数据: T ≤ 1000, x ≤ 10000。
100%的数据: 1 ≤ T ≤ 2 * 10^5, 1 ≤ x ≤ 10^7
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define SIZE 10000050  //由最大的数据10^7决定数组的size
int N[SIZE] = {0}; //数组下标i代表数字,N[i]为-1时,表示不符合条件,否则N[i]为i,表示符合条件

void Init(int SIZE)
{    
    //构建数组
    int tmp = 0, idx = 0;

    for(int i = 1; i <= SIZE; i++ )
    {
        if(N[i] == -1) continue;//已经确定不符合条件的不再判断

        tmp = N[i] = i;//对于未进行判断的,先假定符合,赋值为i
        
        //判断含9
        while(tmp)
        {
            if(tmp % 10 == 9)
            {
                N[i] = -1;//判断为不符合
                break;
            }
 
            tmp /= 10;
        }

        //如果为已经判断不合条件,其倍数一定不符合
        if(N[i] == -1)
        {
            idx = i;
            for(int j = 2; ; j++)
            {
                idx += i; //这里采用了加上本身的方法,判断是否
                if(idx > SIZE) break; //注意判断是否超过数组大小不
 
                N[idx] = -1; 
            }
        }
    }
 
}
  
int main()
{
    Init(SIZE);
 
    int n, d;
    scanf("%d", &n);
  
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &d);
  
        if(N[d] == -1)
        {
            printf("-1\n");
            continue;
        }
  
        int j = d + 1;
        for(; j < _SIZE; j++)
        {
            if(N[j] == -1) continue;
            printf("%d\n", N[j]);
            break;
        }//搜可报出的数
  
        if(j == SIZE) printf("-1\n"); //超出范围
    }
  
    return 0;
}
思路勘误:

(1) 对数字范围不确定,int即可表示所有数字;

(2)对于是否是含有9的数的倍数,在得到含有9的数字的同时就排除了其倍数,比除法判断要好;

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值