首页 > 其他 > 详细

luogu p1037 产生数双做法

时间:2020-05-05 22:08:07      阅读:84      评论:0      收藏:0      [点我收藏+]

题目见洛谷

eee

//图论做法+高精
#include <iostream>
#include <string>
using namespace std;
string str;
int k,vis[10][10],f[10],num[101];
inline void floyd() {  //弗洛伊德
  for (int k = 0;k <= 9;k++)
    for (int i = 0;i <= 9;i++)
      for (int j = 0;j <= 9;j++) vis[i][j] = vis[i][j] || (vis[i][k] && vis[k][j]);
}
int main (){
  ios::sync_with_stdio(false);
  cin >> str >> k;
  while (k--) {
    int a,b;
    cin >> a >> b;
    vis[a][b] = true;  //a可以变成b
  }
  for (int i = 0;i <= 9;i++) vis[i][i] = true;  //自己可以变成自己
  floyd();
  for (int i = 0;i <= 9;i++)
    for (int j = 0;j <= 9;j++)
      if (vis[i][j]) f[i]++;  //求出i可以变成多少种数字
  int len = 2; num[1] = 1;
  
  
  for (int i = 0;i < (int)str.length();i++) {  //高精度
    for (int j = 1;j <= 100;j++) num[j] *= f[str[i]-0];
    for (int j = 1;j <= 100;j++)
      if (num[j] >= 10) {  //进位
        num[j+1] += num[j]/10;
        num[j] %= 10;
      }
    while (num[len]) len++;  //求出长度
  }
  for (int i = len-1;i >= 1;i--) cout << num[i];  //输出
  return 0;
}
inline void dfs(int x)
{
	vis[x]=1;//将搜到的做标记 
	ans++;
	for(int i=1;i<=k;i++)
		if(a[i]==x&&!vis[b[i]])
		dfs(b[i]);//如果符合且未被搜索
}
dfs原理类似但好像更快一点

  

对每一位数字进行DFS

每搜索到一个数字计数器加一。

最后根据分步计算原理,将每位数可扩展的数进行相乘输出即可

luogu p1037 产生数双做法

原文:https://www.cnblogs.com/shikeyu/p/12833071.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!