【C】关于打表法的简单介绍

版权声明:Copyright © 2019年 Lcost. All rights reserved. https://blog.csdn.net/m0_43448982/article/details/85849138

本文只是简单介绍打表法,各位大佬可以忽略本文,如果有大佬对本文有修改意见,欢迎评论
还是先上OJ题目
这是一道浙江工业大学的OJ题目,由于是内网链接,这里只能给出题号了:1677(题目有一定的修改,主要是为了体现打表法的优势)

数1的个数

题目描述

给定一个十进制正整数n(1<=n<=10000),写下从1到n的所有整数,然后数一下其中出现的数字“1”的个数。
例如当n=2时,写下1,2.这样只出现了1个“1”;当n=12时,写下1,2,3,4,5,6,7,8,9,10,11,12。这样出现了5个“1”。

输入

有多组输入,每组输入占一行。每一行有一个数字n。

输出

对于每组输入,输出一行,每行一个正整数,即“1”的个数。

样例输入

2
12

样例输出

1
5

分析

如果让一个熟悉编程的人来写,这题应该不算难,那这里就对核心的判断部分就一句话带过了

将每一个小于等于n的数字遍历过去,每一个数字进行拆分得到其中的“1”的个数,累加起来即是答案

#include<stdio.h>

int main()
{
    int n,i,sum;
    while (scanf("%d",&n)!=EOF)
    {
        sum=0;
        for (i=1; i<=n; i++)//遍历小于等于n的所有数
        {
            int temp=i;
            int onenumbers=0;
            while (temp)//拆分
            {
                if (temp%10==1)
                {
                    onenumbers++;
                }
                temp/=10;
            }
            sum+=onenumbers;
        }
        printf("%d\n",sum);
    }
    return 0;
}

但是呢,我们发现几个问题:

  1. 无论是100还是200,这两组数据都需要计算100以内的数字的“1”的个数,而且过程完全相同。
  2. 如果我们先输入1000,然后再输入200。实际上,200这个数据早就被计算过了,而这个代码却会去重复计算,浪费时间+内存+电量。
  3. 题目要求的数据范围不大,只有1-10000个数字,每一个数字有对应的一个唯一确定的输出。

这个时候我们就要学会使用打表法

什么是打表

打一张表格,把需要的东西都保存下来
这里我们就直接上示例代码了:

#include<stdio.h>

int main()
{
	int f[10010];//这里保存了所有可能的结果
    int n,i,sum=0;
    for (i=1; i<=10000; i++)//遍历小于等于n的所有数
    {
    	int temp=i;
        int onenumbers=0;
        while (temp)//拆分
        {
            if (temp%10==1)
            {
                onenumbers++;
            }
            temp/=10;
        }
        sum+=onenumbers;
        f[i]=sum;
    }
    while (scanf("%d",&n)!=EOF)
    {
        printf("%d\n",f[n]);
    }
    return 0;
}

我们可以看到,这个程序输入输出仅仅只有3行(其实完全可以只有一行的)而能够让我们这么快的输入输出得益于上面这个打表的过程。

猜你喜欢

转载自blog.csdn.net/m0_43448982/article/details/85849138