Description
牛牛得到了一堆神奇的恶魔果实,每个恶魔果实都给了牛牛一个改变数字的能力,可以把数字a变成数字b,现在牛牛有一个数字x,他想知道吃完这n个恶魔果实后,他可以把数字x变成多少种的数。
注:每一个恶魔果实的能力可以重复使用多次,当然也可以不用,存在相同能力的恶魔果实.
Solution
莫名其妙wa了很多次,一开始思路是直接dfs,每个数字变或不变,for找当前的数字能否到达1~9数字
然后tle了,考虑从图论的角度,可以用floyd处理出每个数字之间能否相互到达。
之后运用乘法原理,即每位数字能够有多少种情况,撑起来就可以啦。
不要忘记自己能到到达自己,对给自己连上一条边。
Code
#include<bits/stdc++.h>
typedef long long ll;
const int N = 1e6 + 5;
const int mod = 1e4 + 7;
using namespace std;
int maze[15][15];
int g[15][15];
ll vis[15];
string now;
int len;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int x, n;
cin >> x >> n;
while(x) {
int tmp = x % 10;
now += tmp + '0';
x /= 10;
maze[tmp][tmp] = 1;
len++;
}
reverse(now.begin(), now.end());
for(int i = 1; i <= n; i++) {
int l, r;
cin >> l >> r;
maze[l][r]++;
}
for(int k = 0; k <= 9; k++) {
for(int i = 0; i <= 9; i++) {
for(int j = 0; j <= 9; j++) {
maze[i][j] = maze[i][j] || (maze[i][k] && maze[k][j]);
}
}
}
for(int i = 0; i <= 9; i++) {
for(int j = 0; j <= 9; j++) {
if(maze[i][j]) {
vis[i]++;
}
}
//cout << i << ' ' << vis[i] << "\n";
}
ll ans = 1;
for(int i = 0; i < now.size(); i++) {
int p = now[i] - '0';
ans *= (vis[p]);
ans %= mod;
}
cout << ans << "\n";
return 0;
} 
京公网安备 11010502036488号