1361:产生数(Produce)

【解题思路】
1、将数字拆分保存在数组中,而后转换每一位。
2、将数字变化规则保存在x、y两个一维数组中,x[i]到y[i]是一种转换规则。
3、从n的初始值开始搜索,对n做数字拆分,将拆分后的各位数字保存在一个数组中。针对数组中的每位数字,看能否通过转换规则将该数字转换为另一个数字。如果可以,那么做一次转换,将该数组通过数字组合变为一个整数,通过vis数组判断该整数是否出现过。如果出现过,那么略过。如果没出现过,将该整数在vis数组中设为“出现过”,产生的数字个数加1,而后从该整数开始再次进行搜索。

输入样例分析
234
2
2 5
3 6

【参考代码】

广搜

#include<bits/stdc++.h>
using namespace std;
#define K 20
int n, k, ct, x[K], y[K], arr[5], ai;
bool vis[10001];
void toArr(int num)//将整数num进行数字拆分,结果保存在数字数组arr中。(包括num为0的情况) 
{
    ai = 0;
    int a = num;
    do
    {
        arr[++ai] = a % 10;
        a /= 10;
    }while(a > 0);    
}
int toNum()//将数字数组arr保存的数字转为整型数字 
{
    int num = 0;
    for(int i = ai; i >= 1; --i)
        num = num * 10 + arr[i];
    return num;
}
void bfs()
{
	queue<int> que;
	vis[n] = true;
	ct = 1;
	que.push(n);
	while(que.empty() == false)
	{
		int u = que.front();
		que.pop();
		toArr(u);//将u转为数字数组arr 
		for(int i = 1; i <= ai; ++i)//遍历arr中的每一位 
		{
			for(int j = 1; j <= k; ++j)//遍历每条规则 
			{
				if(arr[i] == x[j])
				{
					arr[i] = y[j];
					int newNum = toNum();
					if(vis[newNum] == false)
					{
						vis[newNum] = true;
						ct++;
						que.push(newNum);
					}
					arr[i] = x[j];//还原 
				}
			}
		}
	}
}
int main()
{
	cin >> n >> k;
	for(int i = 1; i <= k; ++i)
		cin >> x[i] >> y[i];
	bfs();
	cout << ct;
	return 0;
}

深搜

#include <bits/stdc++.h>
using namespace std;
int n, k, x[20], y[20], arr[5], ai, ct;
bool vis[10000];
void toArr(int num)//将整数num进行数字拆分,结果保存在数字数组arr中。(包括num为0的情况) 
{
	ai = 0;
    int a = num;
    do
    {
        arr[++ai] = a % 10;
        a /= 10;
    }while(a > 0);    
}
int toNum()//将数字数组arr保存的数字转为整型数字 
{
    int num = 0;
    for(int i = ai; i >= 1; --i)
        num = num * 10 + arr[i];
    return num;
}
void dfs(int num)
{
    int temp, newNum;
    for(int i = 1; i <= ai; ++i)
    {
        for(int j = 1; j <= k; ++j)//如果存在替换arr[i]的规则 
        {
            if(arr[i] == x[j])
            {
                arr[i] = y[j];
                newNum = toNum();//合成得到新的整数 
                if(vis[newNum] == false)//如果新的整数nweNum没出现过 
                {
                    vis[newNum] = true;//将newNum标记为出现过 
                    ct++;//数字出现的个数加1 
                    dfs(newNum);
                }
                arr[i] = x[j];//还原 
            }
        }
    }
}
int main()
{
    cin >> n >> k;
    for(int i = 1; i <= k; ++i)
        cin >> x[i] >> y[i];
    toArr(n);
    vis[n] = true;
    ct = 1;
    dfs(n);
    cout << ct;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值