一、问题描述
二、问题分析
1、暴力枚举
这是一道填空题,直接 暴力枚举 得到答案即可 (程序可能要跑很久)
我采用了字符串的方法,更方便处理。
#include <bits/stdc++.h>
using namespace std;
int ans = 0;
int main()
{
for (long long i = 11; i <= 100000000; i++)
{
string s = to_string(i);
int a = s.size();
if (a % 2 == 0)
{
int sum1 = 0, sum2 = 0;
for (int j = 0; j < a / 2; j++)
{
sum1 += s[j] - '0';
sum2 += s[a - j - 1] - '0';
}
if (sum1 == sum2)
ans++;
}
}
cout << ans;
return 0;
}
最终得到答案4430091。
2、大佬的解法
乘法原理:通过三层嵌套循环来遍历所有可能的情况。外层循环控制前半部分的位数,中间循环控制数字之和,内层循环控制后半部分的位数。在内层循环中,利用乘法原理将前半部分和后半部分满足条件的数字个数相乘,并累加到答案变量 ans
中。
#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(){
//因为一个数是对称的,左边可以由这些数组成,右边也是一样,所以我们只需要算4位即可
for(int i=1;i<=9999;i++){
get(i);
}
//利用乘法原理来统计数量
int ans=0;
for(int i=1;i<=4;i++) //通过控制变量法,首先确定前半边的位数
{
for(int k=1;k<=i*9;k++) //再控制他们的和-->一个两位数最多是多少(99->2*9->18)
{
for(int j=1;j<=i;j++) //最后后半边,进行变化
{
ans+=a[i][k]*a[j][k];
}
}
}
cout<<ans;
return 0;
}