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;
}