洛谷P1037 产生数 (Floyd联通性问题)
问题描述:
解题思路:
可以利用乘法原理,判断原数上每一位数字有几种变化情况,然后相乘即为答案。
很显然,题目所给的变化情况即为一条边,而每一个数字的变化即为一个连通块,因此单个数字变化的个数即为这个连通块的大小。
判断联通快的算法很多,可以通过
d
f
s
dfs
dfs 和
b
f
s
bfs
bfs 等搜索进行遍历每个连通块,这里我们通过
F
l
o
y
d
Floyd
Floyd 求出
i
i
i 和
j
j
j 是否相连来解决连通块问题。
既
i
i
i 所能到达的所有
j
j
j 都处在同一连通块,至于连通块的大小即为
i
i
i 所能到达的元素个数。
判断联通性的 F l o y d Floyd Floyd 我们可以这么写:
for(int k=0;k<=9;k++)
for(int i=0;i<=9;i++)
for(int j=0;j<=9;j++)
dis[i][j]=dis[i][j]||(dis[i][k]&&dis[l][k]);
//当 dis 为真,即为联通
用这个板子我们就能轻松的过了这道题。
CODE:
#include <bits/stdc++.h>
using namespace std;
string s;
int k;
bool dis[50][50]={false};
int num[20];
__int128 ans=1;
inline void read(__int128 &X) //__int128的读入
{
X = 0;
int w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
if (w) X = -X;
}
void print(__int128 x) //__int128的输出
{
if (!x) return ;
if (x < 0) putchar('-'),x = -x;
print(x / 10);
putchar(x % 10 + '0');
}
int main()
{
cin>>s;
cin>>k;
int a,b;
for(int i=1;i<=k;i++)
{
cin>>a>>b;
dis[a][b]=true;
}
for(int i=0;i<=9;i++) dis[i][i]=true;
for(int l=0;l<=9;l++)
for(int i=0;i<=9;i++)
for(int j=0;j<=9;j++)
dis[i][j]=dis[i][j]||(dis[i][l]&&dis[l][j]);
for(int i=0;i<=9;i++)
{
for(int j=0;j<=9;j++)
if(dis[i][j])
num[i]++; //每个数字所在的连通块的大小
}
for(int i=0;i<s.size();i++)
ans*=max(1,num[s[i]-'0']);
print(ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!