Generate number problem solution (DFS+count)

Title description

Give an integer n (n<10 30 ) and k transformation rules (k<=15).
Rule:
One digit can be transformed into another one digit:
the right part of the rule cannot be zero.
For example: n=234. There are rules (k=2):
2->5
3->6
The integer 234 above after transformation may produce an integer (including the original number):
234
534
264
564
4 different generated numbers
Question:
Given An integer n and k rules.
Find out:
How many different integers can be produced after any number of transformations (0 or more times).
Only the number of outputs is required.

enter

Keyboard input, the format is:
  nk
  x1 y1
  x2 y2
  ……
  xn yn

Output

Screen output, the format is: an integer (the number that meets the condition)

Sample input

234 2
2 5
3 6

Sample output

4

The title description of the question is easy to mistakenly think it is a search question, but it is not. Take the worst case such as the following input data:
111111111111111111111111111111 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 1
There are 9 choices for each digit. The answer is 9 30 == 42391158275216203514294433201, and the search will definitely time out.
The positive solution is to first perform a DFS on each number to find out the possible transformations of each number, and finally use the principle of multiplication and counting to calculate all the final possible situations bit by bit. The result requires high-precision storage.

#include<bits/stdc++.h>
#define ll long long
#define next next_
using namespace std;
ll len,k,u[22],v[22],num[11];
string s,ans="1";
bool vis[11];
void dfs(ll t){
    
    
	vis[t]=true;
	for(ll i=1;i<=k;i++){
    
    
		if(u[i]==t){
    
    
			if(!vis[v[i]]){
    
    
				vis[v[i]]=true;
				dfs(v[i]);
			}
		}
	}
}
string its(ll a){
    
    
	stringstream ss;
	ss<<a;
	string str=ss.str();
	return str;
}
string mul(string a,string b){
    
    
	string s="";
	int lena=a.size();
	int lenb=b.size();
	int aa[1010],bb[1010],cc[1010];
	memset(aa,0,sizeof(aa));
	memset(bb,0,sizeof(bb));
	memset(cc,0,sizeof(cc));
	for(int i=1;i<=lena;i++) aa[i]=a[lena-i]-'0';
	for(int i=1;i<=lenb;i++) bb[i]=b[lenb-i]-'0';
	for(int i=1;i<=lena;i++){
    
    
		for(int j=1;j<=lenb;j++){
    
    
			cc[i+j-1]+=aa[i]*bb[j];
			if(cc[i+j-1]>=10){
    
    
				cc[i+j]+=cc[i+j-1]/10;
				cc[i+j-1]%=10;
			}
		}
	}
	if(cc[lena+lenb]) s+=cc[lena+lenb]+'0';
	for(int i=lena+lenb-1;i>=1;i--) s+=cc[i]+'0';
	return s;
}
int main(){
    
    
	cin>>s;
	len=s.size();
	scanf("%lld",&k);
	for(ll i=1;i<=k;i++)
		scanf("%lld%lld",&u[i],&v[i]);
	for(ll i=0;i<=9;i++){
    
    
		for(ll j=0;j<=9;j++) vis[j]=false;
		dfs(i);
		for(ll j=0;j<=9;j++) if(vis[j]) num[i]++;
	}
	for(ll i=0;i<len;i++)
		ans=mul(ans,its(num[s[i]-'0']));
	cout<<ans;
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_50808324/article/details/113097509