• LFYZ-OJ ID: 1019 位数问题


    位数问题

    问题描述

    在所有的N位数中,有多少个数中有偶数个数字3?由于结果可能很大,你只需要输出这个答案对12345取余的值。

    INPUT

    输入一个数N(1<=N<=1000),输入以0结束。

    OUTPUT

    对于每一个N输出有多少个数中有偶数个数字3。

    Sample Input

    2
    0

    Sample Output

    73

    分析

    已知N的最大值为1000,1000位的数字的个数约有101000个,这是个天文数字,故不可能使用枚举法一一统计。本题需使用递推的思想:

    设E(n)为n位数中有偶数个3的数字个数,O(n)为n位数中有奇数个3的数字个数。从n位数转变为n+1位数可以在n位数的基础上增加一位:

    偶数的英文为“Even”, 奇数的英文为“Odd”,在这里“O(n)”可能会和时间复杂度的概念混淆,小心避免理解出错。

    • 如果n位数中有偶数个3,新增一个数位为3,则n+1位数中有奇数个3
    • 如果n位数中有偶数个3,新增一个数位为非3,则n+1位数中有偶数个3
    • 如果n位数中有奇数个3,新增一个数位为3,则n+1位数中有偶数个3
    • 如果n位数中有奇数个3,新增一个数位为非3,则n+1位数中有奇数个3

    递推关系用公式表达如下:

    • E(n+1)=E(n)*9+O(n) => E(n)=E(n-1)*9+O(n-1)
    • O(n+1)=E(n)+O(n)*9 => O(n)=E(n-1)+O(n-1)*9

    1位数有10个:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 数字3中有奇数个(1个)数字3,其它9个数字中有偶数个(0个)数字3,因此E(1)=9, O(1)=1,这就是递推的已知条件,也是我们递推的起点。但在递推的时候,数字的第一位是不能为0的,所以递推到第一位(我们从低位往高位推)时,不是乘9,而是乘8。

    当N很大时,数字必定会超过int能够表达的范围从而导致溢出,所以在递归过程中要不断的按照题目要求和12345求余以将数字控制在一定范围内。

    通过递推计算,时间复杂度为O(N)。

    代码示例

    #include<iostream>
    using namespace std;
    int EVEN[1001], ODD[1001];		//Even存储偶数项,ODD存储奇数项
    int main(){
    	int N, x=9;
    	scanf("%d", &N);
    	EVEN[1]=9;                  //递推起点
    	ODD[1] =1;                  //递推起点
    	for(int i=2; i<=N; i++){
    		if(i==N) x=8;           //递推到最高项时
    		EVEN[i]=(EVEN[i-1]*x+ODD[i-1])%12345;
    		ODD[i] =(EVEN[i-1]+ODD[i-1]*9)%12345;
    	}
    	printf("%d", EVEN[N]);
    } 
    
  • 相关阅读:
    jQuery库冲突解决办法
    jquery源码 整体架构
    中文版Chrome浏览器不支持12px以下字体的解决方案
    html5 localStorage
    Git创建分支/GIT提交分支
    Git直接拉取远程分支
    vscode关闭后未打开上次界面的解决办法
    MAC升级nodejs和npm到最新版
    hadoop hue切换中文版
    Hdfs dfs命令使用
  • 原文地址:https://www.cnblogs.com/lfyzoi/p/6875882.html
Copyright © 2020-2023  润新知