列表

详情


NC16742. [NOIP2002]字串变换

描述

已知有两个字串 A, B及一组字串变换的规则(至多6个规则):
A1 -> B1
A2 -> B2
规则的含义为:在A中的子串 A1可以变换为 B1、A2可以变换为 B2 …。
例如:A='abcd' B='xyz'
变换规则为:
‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’
则此时,A 可以经过一系列的变换变为 B,其变换的过程为:
‘abcd’->‘xud’->‘xy’->‘xyz’
共进行了三次变换,使得A变换为B。

输入描述

输入格式如下:
A B
A1 B1 \
A2 B2  |-> 变换规则
... ... /
所有字符串长度的上限为 20。

输出描述

输出格式如下:
若在10步(包含 10步)以内能将A变换为B,则输出最少的变换步数;否则输出"NO ANSWER!"

示例1

输入:

abcd xyz
abc xu
ud y
y yz

输出:

3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 497ms, 内存消耗: 428K, 提交时间: 2023-06-23 17:08:16

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int res=1007;
int tot=1;

string st,ed;
string a[107],b[107];

void dfs(string str,int cnt){
	if(cnt>10||cnt>=res) return ;
	if(str==ed){
		res=min(res,cnt);
		return ;
	}
	
	for(int i=1;i<=tot;i++){
		int p=str.find(a[i]);
		if(p==-1) continue;
		str.replace(p,a[i].size(),b[i]);
		dfs(str,cnt+1);
		p=str.find(b[i]);
		str.replace(p,b[i].size(),a[i]); 
	}
}

int main(){
	cin>>st>>ed;
	while(cin>>a[tot]>>b[tot]) tot++;
	tot--;
	dfs(st,0);
	if(res>10) cout<<"NO ANSWER!";
	else cout<<res;
}

C++(clang++ 11.0.1) 解法, 执行用时: 444ms, 内存消耗: 456K, 提交时间: 2022-08-08 16:00:40

#include <bits/stdc++.h>
using namespace std;
int cur, res = INT_MAX;
string a, b;
string s[10], t[10];
void dfs(string u, int cnt){
	if (cnt > 10 || cnt >= res) return;
	if (b == u){
		res = min(cnt, res);
		return;
	}
	for (int i = 0; i < cur - 1; ++ i){
		int p = u.find(s[i]);
		if (p == -1) continue;
		u.replace(p, s[i].size(), t[i]);
		dfs(u, cnt + 1);
        p = u.find(t[i]);
        u.replace(p, t[i].size(), s[i]);
	}
}
int main(){
	cin >> a >> b;
	while (cin >> s[cur] >> t[cur ++ ]);
	dfs(a, 0);
	if (res > 10) cout << "NO ANSWER!";
	else cout << res;
	return 0;
}

上一题