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;
}
题目死磕过的,感觉被磕的鼻青脸肿。。。
和题目
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;
}
相关文章推荐
- POJ 2282-The Counting Problem(组合数学_区间计数)
- POJ 2282 && HDU 1663 The Counting Problem(数论)
- poj 2282 The Counting Problem 按位统计
- Poj 2282 The Counting Problem[统计区间 0 - 9出现的次数]
- POJ 2282 The Counting Problem
- POJ 2282 The Counting Problem & POJ 3286 How many 0's?(按位计算贡献)
- POJ题目2282 The Counting Problem(数学)
- poj2282 The Counting Problem
- poj 2282 The Counting Problem (数位DP)
- poj 2282 The Counting Problem && poj 3286 How many 0's? (数位dp)
- 统计区间[a,b]各个数字出现的个数:poj 2282 The Counting Problem poj 3286
- POJ 2282 The Counting Problem
- The Counting Problem - POJ 2282 数位dp
- POJ 2282 The Counting Problem
- POJ2282:The Counting Problem(数位DP)
- POJ 2282 The Counting Problem,组合数学
- (Realx 数论1.28)POJ 2282 The Counting Problem(区间统计数字:统计a、b之间各个数字(0~9)出现的次数)
- [POJ] 2282 -> The Counting Problem
- POJ 2282 The Counting Problem (数位dp)
- poj 2282 The Counting Problem & 3286 How many 0's?