poj 2282

按位统计,,,先算各位,,个位是2的情况有413种,,,因为各位左边可以0~412,,,而右边没有数字,,,

然后是十位,,,十位是2的有41*10 + 1*4种,,当左边从0~40时,,,右边可以从0~9,,,而左边为41时,,右边只能从0~3

然后是百位,,,,百位有4*100种,,,,即左边从0~3,,右边从0~99

千位有  1*1000,,,左边没有数字,,,右边0~999,,,,

上面是计算1~9,,,,计算0的时候比较特殊,,,,原因是除了0这一个数字之外,,,,0不能做开头,,,

可以看到在求1~9的个数的时候,,,都是分为2部分相乘,,,这样0的处理也很简单,,只需把相乘的左半部分-1,,,,

代码:

#include<iostream>
#include<fstream>

using namespace std;

void solve(long long s,long long ans[]){
	int i,j,k;
	if(s<0) return;
	long long rgt=0,id=1;
	ans[0]+=1;
	while(s>0){
		int now=s%10;
		s/=10;
		for(i=0;i<10;i++)
		{
			if(now>i)
			{
				ans[i]+=s*id;
				if(i) ans[i]+=id;
			}
			else
				if(now==i)
				{
					if(s&&i==0)
						ans[i]+=(s-1)*id+rgt+1;
					else
						if(i>0)
							ans[i]+=s*id+rgt+1;
				}
				else
					if(now<i)
						ans[i]+=s*id;
		}
		rgt+=now*id;
		id*=10;
	}
}



void read(){
//	ifstream cin("in.txt");
	int i;
	long long s,t;
	long long ans[11];
	
	while(cin>>s>>t)
	{
		if(s==0&&t==0) return;
		memset(ans,0,sizeof(ans));
		if(s>t)
			swap(s,t);
		solve(s-1,ans);
		for(i=0;i<10;i++)
			ans[i]=-ans[i];
		solve(t,ans);
		for(i=0;i<10;i++)
			cout<<ans[i]<<' ';
		cout<<endl;
	}
}

int main(){
	read();
	return 0;
}

posted on 2011-04-05 13:09  宇宙吾心  阅读(605)  评论(0)    收藏  举报

导航