uva 129

题目链接

dfs 主要是判断当前加入这个字母后是否满足无两个相邻的子串。

因为每一个先前的串全都是满足题意的,要每次判断当前的串是否满足题意。用判断后缀的方法就可以了。(比如 有长度为6的串,当前变为7了,不用判断,23,45,是不是一样,因为之前已经处理过了)
取最后一个和倒数第一个,取倒数两个和倒数两个前面的两个,…。
j 就是所取的子串的长度 ,cur是从0开始的,所以长度要加1

for(int j=1;j*2 <= cur + 1;j++)
{
	bool ok = true;
	for(int k=0;k<j;k++)
		if(a[cur-k] != a[cur-k-j])
		{
			ok = false;
			break;
		}
}

判断完后,当 cnt(处理到的第cnt个数)等于 n时,就输出结果
这里输出处理不小心就PE.

if(cnt++ == n)
	{
		int mm = 0,nn = 0; bool plas = false;
		for(int i=0;i<cur;i++)
		{
			if(mm == 0)
			{
				if(!plas) plas = true;
				else putchar(' '),mm = 0;
			}
			cout<<char(a[i]+'A');
			mm ++;
			if(mm == 4) mm = 0,nn ++;
			if(nn == 16) nn = 0,plas = false,puts("");
		}
		cout<<"\n"<<cur<<endl;
		return 0;
	}

最后就是dfs的返回值,返回值决定了是否再递归下去,当已经确定结果的时候,就不用递归下去了,返回0

总代码

#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 1e9+7;
const int N = 210;

int n,m,cnt;
int a[N];

int dfs(int cur)
{
	if(cnt++ == n)
	{
		int mm = 0,nn = 0; bool plas = false;
		for(int i=0;i<cur;i++)
		{
			if(mm == 0)
			{
				if(!plas) plas = true;
				else putchar(' '),mm = 0;
			}
			cout<<char(a[i]+'A');
			mm ++;
			if(mm == 4) mm = 0,nn ++;
			if(nn == 16) nn = 0,plas = false,puts("");
		}
		cout<<"\n"<<cur<<endl;
		return 0;
	}
	for(int i=0;i<m;i++)
	{
		a[cur] = i;
		bool plas = true;
		for(int j=1;j*2 <= cur + 1;j++)
		{
			bool ok = true;
			for(int k=0;k<j;k++)
				if(a[cur-k] != a[cur-k-j])
				{
					ok = false;
					break;
				}
			if(ok)//ok是true说明有相同的子串,就要不得
			{
				plas = false;
				break;
			}
		}
		if(plas) if(!dfs(cur+1)) return 0;
	}
	return 1;
}

int main(){
	while(cin>>n>>m && n && m) cnt = 0,dfs(0);
	
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值