您的位置:首页 > 其它

POJ - 2282 - The Counting Problem - (计数问题)

2018-02-07 11:06 344 查看
题目链接:http://poj.org/problem?id=2282

题目死磕过的,感觉被磕的鼻青脸肿。。。

和题目
POJ - 3286 - How many 0's? - (统计0的个数)的思想一样,明白那道题这道题就差不多了,只是这里不单单统计0的个数。所以对于当前统计位上的值如果不为0,那么它的前面高位的组合可以为0,。

代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define M 15
ll ansa[M],ansb[M];
void solve(ll n,ll sum[])
{
ll div=10;
int t,i;
for(i=0;i<=9;i++) //初始化位0
sum[i]=0;
if(n<10)
{
for(i=1;i<=n;i++)//n小于10的话直接统计输出(没有出现0)
sum[i]=1;
return;
}
//统计每一位上每个数字出现的方案数
while(n/div) //div有几个0,处理的就是第几位
{
t=(n%div)/(div/10);//当前位的值(t能从最低位取到第二高位)

//n的高位组合为n/div,先使得枚举的高位组合取到n/div-1,那么低位任意组合都会小于n
sum[0]+=(n/div-1)*(div/10); //当前位是0,前面高位的组合不能取空(可取[1,n/div-1])
for(i=1;i<=9;i++)
sum[i]+=(n/div)*(div/10); //当前位非0,前面可以取空(可取[0,n/div-1])

//枚举高位组合为n/div时
for(i=0;i<t;i++) //由于当前位值为t,枚举当前位的值小于t时
sum[i]+=(div/10);
sum[t]+=n%(div/10)+1;

div=div*10;
}

//计算最高位
div=div/10;
t=n/div; //t是最高位的值
for(i=1;i<t;i++)
sum[i]+=div;
sum[t]+=n%div+1;
}
int main()
{
ll a,b;
while(scanf("%lld%lld",&a,&b)!=EOF)
{
if(a==0&&b==0)
break;
if(a>b)
swap(a,b);

solve(b,ansb);
solve(a-1,ansa);

for(int i=0;i<=8;i++)
printf("%lld ",ansb[i]-ansa[i]);
printf("%lld\n",ansb[9]-ansa[9]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: