思路:
判断数是否合法。前导零
for(int i=1;i<=4;i++)
{
for(int j=1;j<=i;j++)
{
for(int k=1;k<=i*9;k++)
{
ans+=a[i][k]*a[j][k];
/*
因为后半部分是由有前导0的,所以k(后半部分的位数)<=i(前半部分的位数)
如 123 015也是 i=3,k=2此时因为有前导0的存在所以将后半部分的位数补全至3位
同时k不大于i保证了不会出现i=2,k=4的情况。
*/
}
}
}
计算一个数的位数和各位的和
void count(int x)
{
int cnt++=0;//计算位数
int sum=0;//各位和
while(x)
{
sum+=x%10;//各位和
cnt++;//位数
x/=10;//更新x
}
a[cnt][sum]++;
}
手写代码
#include<bits/stdc++.h>
using namespace std;
long long a[5][37];
long long ans=0;
void count(int x)
{
int num=0;
int cnt=0;
while(x){//这个条件是否能正确计算位数?
num+=x%10;//计算位数的和
x/=10;
cnt++;
}
//检查-计算
//先检查-计算一次-少一位。如果有一个四位数,第三次计算后只剩下一位,判断符合条件。
//计算后为0,判断-总共进行了四次的计算。
a[cnt][num]++;//符合条件的数加1
}
int main()
{
for(int i=1;i<=9999;i++)
{
count(i);
}
for(int i=1;i<=4;i++)
{
for(int j=1;j<=i;j++)
{
for(int k=1;k<=i*9;k++)
{
ans+=a[i][k]*a[j][k];
}
}
}
cout<<ans;
return 0;
}
样例代码
#include<bits/stdc++.h>
using namespace std;
//这个数组的前一个框表示数的有多少位,后一个是表示这些数位上的数的和,数组存的值表示像这样的数在1~9999有多少个
//至于有什么用请看下面注释(4*9-->因为一个数分两半最多也就每边各4位数,其中最大也就9-->9999 9999)
int a[5][4*9];
//制作 a[5][4*9] 表,数位拆分统计
void get(int x){
int sum=0,num=0;
while(x){
sum+=x%10;
num++;
x/=10;
}
a[num][sum]++; //多少位,和是多少
}
int main(){
for(int i=1;i<=9999;i++){
get(i); //将所有情况全部统计出来
}
//利用乘法原理来统计数量
int ans=0;
for(int i=1;i<=4;i++)
{
for(int j=1;j<=i;j++)
{
for(int k=1;k<=i*9;k++)
{
//这个jk嵌套的顺序不影响
ans+=a[i][k]*a[j][k];
/*
当j=i时,左边:位数为i和为k的数,右边:位数为j和为k
这样就表示总共有偶数个位数(对称)
并且前一半等于后一半
这时候将前后满足条件的数进行组合就是。
起作用的只有j==i的情况,因为其他情况不满足i==j(是偶数)
*/
}
}
}
cout<<ans;
return 0;
}
//对于左右的要求
/*
位数相等(偶数个数位)
和相等
*/

156

被折叠的 条评论
为什么被折叠?



