当前位置: 代码迷 >> 综合 >> 1049 Counting Ones (数学)
  详细解决方案

1049 Counting Ones (数学)

热度:63   发布时间:2024-02-25 15:51:06.0

1049 Counting Ones (数学)

思路:考虑对数的每一位贡献进行计算。

假设对于当前位:nownownow,其对应的111开头后面全为0的数为:aaa

123451234512345,假设now=4now=4now=4a=10a=10a=10now=2,a=1000now=2,a=1000now=2,a=1000

nownownow左边组成的数为:lll,右边组成的数为:rrr

分情况讨论:

1.now=01.now=01.now=0

这种情况:该位为111的贡献只能在left∈[0,l?1]left\in[0,l-1]left[0,l?1]产生,一共lll种情况。

而右边的贡献为right∈[0,a?1]right\in[0,a-1]right[0,a?1],共aaa种情况。

根据乘法原理有:contribution=l×acontribution=l\times acontribution=l×a种情况。

2.now=1now=1now=1

这种情况与上面相比,还需考虑当左边为lll时,右边可以为[0,r][0,r][0,r]

所以还要加上r+1r+1r+1

contribution=l×a+r+1contribution=l\times a+r+1contribution=l×a+r+1

3.now>1now>1now>1

这种情况left∈[0,l]left\in[0,l]left[0,l]right∈[0,a?1]right\in[0,a-1]right[0,a?1]

contribution=(l+1)×acontribution=(l+1)\times acontribution=(l+1)×a

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define il inline
#define ios ios::sync_with_stdio(false),cin.tie(0)
int n,ans,l,r,a=1,now;
int main(){
    scanf("%d",&n);while(n/a){
    l=n/(a*10),r=n%a,now=n/a%10;if(!now) ans+=l*a;else if(now==1) ans+=l*a+r+1;else ans+=(l+1)*a;a*=10;}printf("%d\n",ans);return 0;
}
  相关解决方案