这就是国赛的威力吗,第一题就这么难。我真的想不到用动态规划,这道题让我用暴力+前缀和做出来了。
本来是纯暴力的,直接四重循环,电脑跑了好久才出来一个数,但是不对(其实是因为没有开long long)。然后我就用前缀和,计算最后一个数3在末尾的个数。相当于前三重循环确定前三个数的位置,现只需要知道最后的区间中3的个数,就能得到该情况下的个数。
很快就跑出来了,但是结果和之前的值一样,我一拍脑门,开了个longlong,OK,过了。
答案:5484660609
丑陋的暴力前缀和:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool check(int a)
{
while (a)
{
int temp = a % 10;
if (temp == 2 || temp == 0 || temp == 3)
return true;
a /= 10;
}
return false;
}
int main()
{
string str;
long long ans = 0;
for (int i = 1; i <= 2023; i++)
{
if (check(i)) //判断有没有2 0 3
{
string temp = to_string(i);
for (auto it : temp)
if (it == '2' || it == '0' || it == '3')
str += it;
}
}
//3的前缀和
vector<int>s(str.size());
for (int i = 1; i < str.size(); i++)
{
if (str[i] == '3')
s[i] = s[i - 1] + 1;
else s[i] = s[i - 1];
}
//cout << str << endl; 观测
for (int i = 0; i < str.size(); i++) //2
{
if (str[i] == '2')
for (int j = i + 1; j < str.size(); j++) //0
{
if (str[j] == '0')
for (int k = j + 1; k < str.size(); k++) //2
{
if (str[k] == '2')
ans += s.back() - s[k];
}
}
}
cout << ans;
return 0;
}