题目1491:求1和2的个数

题目描述:

给定正整数N,函数F(N)表示小于等于N的自然数中1和2的个数之和,例如:1,2,3,4,5,6,7,8,9,10序列中1和2的个数之和为3,因此F(10)=3。输入N,求F(N)的值,1=<N<=10^100(10的100次方)若F(N)很大,则求F(N)mod20123的值。

题意要求找出1-N之间的数中1和2出现的次数,只要找出1出现的次数,2同理可得。

参考《编程之美》上1的数目,该题需要找规律,又是规律题,清华的机试给跪了~~~

总结规律如下:N=abcde

找出百位上可能出现1的次数num:(假设以百位为基准,更高位数值为iHighNumber=a*10+b,地位数组为iLowNumber=d*10+e)

若c<1,则num取决于更高位数字,num=iHighNum*100;

若c==1,则num取决于更高位数字,也受到低位影响,num=iHighNum*100+iLowNumber+1;

若c>1,则num取决于更高为数字,num=(iHighNum+1)*100;

其它位上可能出现1的次数同理可依次求出。

程序代码如下:

#include <cstdio>
#include <cstring>

int mod(int x){
	return x%20123;
}

int Sumls(char *str,int version)
{
	int length=strlen(str),curPos=length-1,power=0,iFactor=1;
    int iCount=0;
    while(curPos>=0)
    {
		int iLowerNum=0,iCurNum=0,iHigherNum=0;
		for(int i=curPos+1;i<length;i++){
			iLowerNum=mod(mod(iLowerNum*10)+str[i]-'0');
		}
        iCurNum=str[curPos]-'0';
		for(int i=0;i<curPos;i++){
			iHigherNum=mod(mod(iHigherNum*10)+str[i]-'0');
		}
		if(iCurNum<version){
			iCount=mod(iCount+iHigherNum*iFactor);
		}
		else if(iCurNum==version){
			iCount=mod(iCount+iHigherNum*iFactor+iLowerNum+1);
		}
		else{
			iHigherNum++;
			iCount=mod(iCount+iHigherNum*iFactor);
		}
		--curPos;
		iFactor=mod(iFactor*10);
    }
    return iCount; 
}

int main()
{
    char str[103];
	while(~scanf("%s",str)){
		int res1=Sumls(str,1);
		int res2=Sumls(str,2);
		int res=res1+res2;
		printf("%d\n",mod(res));
	}
    return 0;
}

总结:注意找规律,盘活整个程序。

转载于:https://www.cnblogs.com/cjweffort/archive/2013/03/09/3374878.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值