Balanced Numbers
Time Limit:123MS Memory Limit:1572864KB 64bit IO Format:%lld
& %llu
Submit Status Practice SPOJ
BALNUM
Description
Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if:
1) Every even digit appears an odd number of times in its decimal representation
2) Every odd digit appears an even number of times in its decimal representation
For example, 77, 211, 6222 and 112334445555677 are balanced numbers while 351, 21, and 662 are not.
Given an interval [A, B], your task is to find the amount of balanced numbers in [A, B] where both A and B are included.
Input
The first line contains an integer T representing the number of test cases.
A test case consists of two numbers A and B separated by a single space representing the interval. You may assume that 1 <= A <= B <= 1019
Output
For each test case, you need to write a number in a single line: the amount of balanced numbers in the corresponding interval
Example
Input: 2 1 1000 1 9
Output: 147 4
题意:求所给区间中,数位中,奇数的出现偶数次,偶数的出现技术次的个数。
题解:看了别人写的题解才知道,把数压进三进制中,0代表没有,1:奇数次
2:偶数次
比如:
126099这个数:0 1 2 3 4 5 6 7 8 9(三进制中的位数)
1 1 1 0 0 0 1 0 0 2(表示)
于是s=3^0*1+3^1*1+3^2*1+3^6*1+3^9*2
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #define ll long long #define N 1010 using namespace std; int n; ll l,r; int dp[22][58888]; int num[22]; int p3[20]; void init() { p3[0]=1; for(int i=1; i<=10; i++) p3[i]=p3[i-1]*3; } int new_s(int s,int d) { int ss=0; int b[12]; memset(b,0,sizeof b); int l=0; while(s) { b[l++]=s%3; s/=3; } b[d]+=1; if(b[d]==3)b[d]=1;///出现3次,奇数次,变为1 for(int i=0; i<=9; i++) ss+=p3[i]*b[i]; return ss; } ///判断是不是每一位数是否满足:奇数的都出现欧数次,偶数的都出现欧数次 bool judge(int s) { for(int i=0; i<=9; i++) { int x=s%3; s/=3; if(x==0)continue; ///没出现 ///不符合:奇数的都出现欧数次,偶数的都出现欧数次 if(x==1&&(i&1))return 0; if(x==2&&!(i&1))return 0; } return 1; } ///模板 int dfs(int i,int s,bool e,bool lze) { if(i==-1)return lze?0:judge(s); if(!e&&dp[i][s]!=-1)return dp[i][s]; ll res=0; int u=e?num[i]:9; for(int d=0; d<=u; d++) { if(lze) {///是前导0 if(d==0)res+=dfs(i-1,s,e&&d==u,lze); else res+=dfs(i-1,new_s(s,d),e&&d==u,lze&&d==0); } else res+=dfs(i-1,new_s(s,d),e&&d==u,lze&&d==0); } return (e)?res:dp[i][s]=res; } int solve(ll x) { int len=0; while(x) { num[len++]=x%10; x/=10; } return dfs(len-1,0,1,1); } int main() { //freopen("in.txt","r",stdin); cin>>n; init(); memset(dp,-1,sizeof dp); while(n--) { scanf("%lld%lld",&l,&r); printf("%d\n",solve(r)-solve(l-1)); } return 0; }