POJ 3087 - Shuffle‘m Up

好久没刷题了呜呜呜,找个搜索题来康康吧

 

 

题目大意:两副牌按照交叉的方式洗牌能不能形成目标组合,如果不能就重新再分为两副牌再次交叉洗牌

DFS:无法完成的情况就是有某次洗牌的结果在之前出现过一次,形成了一个循环,可是还没有达到目标组合。关于处理这个我一开始写的是将所有出现的组合存在一个数组里面,然后每形成一个新的组合就查一遍数组看看有没有相同的,如果没有就把这个新组合再加进去,如果有并且还没有达到目标组合,就说明不行。可是这样写了一下最后的结果是超时,然后我就去CSDN上看了看,发现一个大佬用的set:

Shuffle‘m Up(模拟、dfs两种方法)

然后我就用了一下嘿嘿然后就过了

#include <cstdio>
#include <iostream>
#include <cstring>
#include <set>
using namespace std ;
const int N = 1e5 + 8 ;
int llll ; 
string s1, s2, tar  ;
int ans, len ;
set<string>se ;
void dfs(int n) {
	string tmp  ;
	for (int i = 0 ; i < len ; i ++) {
		tmp += s2[i], tmp += s1[i] ;

	}
	if (se.count(tmp))
		return ;
	se.insert(tmp) ;
	if (tmp == tar) {
		ans = n ;
		return ;
	} else {
		s1 = s2 = "" ;
		for (int i = 0 ; i < len ; i ++) {
			s1 += tmp[i] ;

		}
		for (int i = len ; i < 2 * len ; i ++) {
			s2 += tmp[i] ;

		}
		dfs(n + 1 ) ;
	}
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	int t ;
	cin >> t ;
	for (int i = 1 ; i <= t ; i ++) {
		se.clear() ;
		ans = -1 ;
		cin >> len ;
		cin >> s1 >> s2 >> tar ;
		dfs(0) ;
		if (ans > 0 )
			ans ++ ;
		cout << i << ' ' << ans << '\n' ;
	}
	return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值