Krypton Factor UVA - 129 and Prime Ring Problem UVA - 524 :回溯法的简单应用

Prime Ring Problem UVA - 524

Krypton Factor UVA - 129

524:

分析:枚举排列加上相邻素数判断,根据问题规模可以列一个素数数组来简化判断。当不符合时回溯,符合时深入递归。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 20;
int is_prime[maxn*3];
int arr[maxn];
bool vis[maxn];
int n;

void init() {
	memset(is_prime, 0, sizeof(is_prime));
	is_prime[0] = is_prime[1] = 0;
	for(int i = 2; i < maxn*3; i++) {
		bool ok = true;
		for(int j = 2; j < i; j++) {
			if(i%j==0) ok = false;
 		}
 		if(ok) is_prime[i] = 1;
	}
}

void search(int cur) {
	if(cur==n && is_prime[arr[0]+arr[n-1]]) {
		cout << arr[0];
		for(int i = 1; i < n; i++)
			cout << " " << arr[i];
		cout << endl;
	}
	else for(int i = 2; i <= n; i++)
		if(!vis[i] && is_prime[i+arr[cur-1]]) {
			arr[cur] = i;
			vis[i] = true;
			search(cur+1);
			vis[i] = false;
		}
}

int main() {
    int Case = 0;
    init();
    while (cin >> n) {
    	memset(arr, 0, sizeof(arr));
    	memset(vis, false, sizeof(vis));
    	arr[0] = 1; 
    	if(Case++) cout << endl;
    	cout << "Case " << Case << ":" << endl;
    	search(1);
    }
    return 0;
}

129:

分析:子集生成加子串判断:我的判断方式是:从后截取长度为j的两个相邻字符串,一共可以截取len/2个。然后一一判断即可。

本题输出卡的比较严,一定要细心!

#include <bits/stdc++.h>
using namespace std;
int n,l;
const int maxn = 10000;
int result[maxn];
int cnt, ans;
void print(int len) {
    for(int i = 0; i < len; i++) {
        if(i%4==0 && i && i%64 && i!=len) 
            cout << " "; 
        if(i%64==0 && i && i!=len) 
            cout << endl;
        cout << char(result[i]+'A');
        ans++;
    }
}


bool dfs(int cur) {
	if(cnt++==n)  {//递归一次生成一个串,直到第n个串输出
	       print(cur);
	   cout << endl;
        return false;
	}
	else {
		for(int i = 0; i < l; i++) {
			bool ok = true;
			result[cur] = i;
			int len = cur+1;
			for(int j = 1; j <= len/2; j++) {//切分成len/2对字符串,长度为j
				string t1 = "", t2 = "";
				for(int k = len-1; k >= len-j; k--)
					t1 = char(result[k]+'A') + t1;
				for(int k = len-j-1; k >= len-2*j; k--)
					t2 = char(result[k]+'A') + t2;
				if(t1==t2) ok = false;
			}
			if(ok) {//无重复相邻子串
				if(!dfs(cur+1)) return false;
			}
		}
	}
    return true;
}

int main() {
	freopen("i.txt","r",stdin);
    freopen("o.txt","w",stdout);
   	while(cin >> n >> l && n && l) {
        cnt = ans = 0;
   		dfs(0);
   	    cout << ans << endl;
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值