例一——逐个枚举
问题描述
小蓝在黑板上连续写下从 1到 2023 之间所有的整数,得到了一个数字序列:S=12345678910111213...20222023。
小蓝想知道S 中有多少种子序列恰好等于 2023?
以下是 3 种满足条件的子序列(用中括号标识出的数字是子序列包含的数字)
1234567891011121314151617181920212223..
1[2]34567891[0]111[2]131415161718192021222[3]...
1[2]34567891[0]111213141516171819[2]021222[3].
注意以下是不满足条件的子序列,虽然包含了 2、0、2、3 四个数字,但是顺序不对:
1[2][3]4567891[0]111[2]1314151617181920212223.
cpp枚举代码
#include "iostream"
using namespace std;
int main()
{
string s;
for(int i=1;i<=2023;i++)
{
//细节一,数字转化字符串——to_string函数
string t=to_string(i);
for(int j=0;j<t.size();j++)
{
//细节二:只保留有用的字符
if(t[j]=='2'||t[j]=='0'||t[j]=='3')
{
s+=t[j];
}
}
}
int n=s.size();
long long ans=0;
for(int i=0;i<n;i++)
{
//细节三:多重循环时遇到不是的直接跳过,无需继续内循环然后再判断
if(s[i]!='2')
{
continue;
}
for(int j=i+1;j<n;j++)
{
if(s[j]!='0')
{
continue;
}
for(int k=j+1;k<n;k++)
{
if(s[k]!='2')
{
continue;
}
for(int l=k+1;l<n;l++)
{
if(s[l]!='3')
{
continue;
}
if(s[i]=='2'&&s[j]=='0'&&s[k]=='2'&&s[l]=='3')
{
ans++;
}
}
}
}
}
cout<<ans;
//5484660609
}
例二——打表
小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0到9的范围之内。数组中的元素从左至右如下所示:
68691612491982364775950387581586
8303792705885709919446863385163467078276
9856561401A094809128502533
现在他想要从这个数组中寻找一些满足以下条件的子序列:
1.子序列的长度为 8;
2.这个子序列可以按照下标顺序组成一个 yyyymmdd 格式的日期,并且要求这个日期是 2023 年中的某一天的日期,
例如 20230902,20231223。
yyyy 表示年份,mm 表示月份,dd 表示天数,当月份或者天数的长度只有一位时需要一个前导零补充。
请你帮小蓝计算下按上述条件一共能找到多少个不同的 2023 年的日期。对于相同的日期你只需要统计一次即可。
cpp代码
#include <iostream>
using namespace std;
int main()
{
int month,day,i,j,sum=0;
int a[100]={5,6,8,6,9,1,6,1,2,4,9,1,9,8,2,3,6,4,7,7,5,9,5,0,3,8,7,5,8,1,5,8,6,1,8,3,0,3,7,9,2,
7,0,5,8,8,5,7,0,9,9,1,9,4,4,6,8,6,3,3,8,5,1,6,3,4,6,7,0,7,8,2,7,6,8,9,5,6,5,6,1,4,
0,1,0,0,9,4,8,0,9,1,2,8,5,0,2,5,3,3};
for(month=1;month<=12;month++)
{
if(month==2)
day=28;
else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
day=31;
else
day=30;
for(int d=1;d<=day;d++)
{
j=0;
int b[8]={2,0,2,3,month/10,month%10,d/10,d%10};//组成这个日期所需要的每一位
for(i=0;i<100;i++)
{
if(a[i]==b[j])
j++;
if(j==8)
{
sum++;
break;
}
}
}
}
cout<<sum;
return 0;
}