例题7-4 素数环 Prime Ring Problem UVA - 524
Posted yichuan-sun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了例题7-4 素数环 Prime Ring Problem UVA - 524相关的知识,希望对你有一定的参考价值。
这道题写了接近两个小时。思路很容易想,但是bug不好调,尤其是这种暴搜的题。没看紫书解析,这道题独立做的。
bug出在下面几个方面
1.由于没有完全搞明白参数的意义,所以递归函数的参数多了1。本应该搜索sech(1,n-1),刚开始我一直搜索成了sech(1,n)。这是因为,第一个参数意为已确定的序列的最后一个参数,第二个参数为剩余的未确定的参数的数量。
2.不知道哪里应该加入元素,应该加入哪个元素,这一点和bug3耦合,导致了答案错误,调试耗费了我很长时间。最后才发现,1应该在递归之外加入,因为它是个异数,如果在递归内非特判加入,就会影响整个递归的结构。其实还是递归过程没有理解透彻。
3.最后循环退出的地方,思考了好久好久:为何最后一个元素一直未被加入答案序列?我用了个小用例,“4”,递归跟踪了一下,才发现原来是递归结构的不合理,参数多了1——如果rmn多了1,整个递归的意思就和我想的不一样了。这我才找到bug1。
4.最后输出时,如何处理首尾相连?我原来用的是每当一个序列确定,就清空当前序列,但是后来发信啊,这样就会影响整个后续结构,因为答案序列是个全局变量,一旦影响到它,就会发生牵一发而动全身的后果。所以后来,我加了个对首元素和尾元素的特判,并且让这个序列正常return,正常递归删除尾元素,这样就不会影响整个结构了。
下面上AC代码
#include <bits/stdc++.h>
#define N 20
using namespace std;
bool used[N];
int isp[N*N]={0,0,1},n; //0为未处理,1为素数,2为合数
vector<int> ans;
void sech(int now,int rmn);
void preope(){
for (int i=1;i<N;i++) {
for (int j=1;j<N;j++) {
if (isp[i+j]==0) {
int sum=i+j;
for (int t=2;t*t<=sum;t++)
if (sum%t==0) isp[sum]=2;
if (isp[sum]==0) isp[sum]=1;
}
}
}
}
int main() {
int cnt=0;
preope();
while (scanf("%d",&n)!=EOF){
if (cnt++) printf("
");
printf("Case %d:
",cnt);
ans.push_back(1);
used[1]=true;
sech(1,n-1);
fill(used,used+n,false);
ans.clear();
}
return 0;
}
void sech(int now,int rmn) {
if (rmn==0) {
if (isp[ans.back()+ans[0]]==1) {
printf("%d",ans[0]);
for (int i=1;i<(int)ans.size();i++)
printf(" %d",ans[i]);
printf("
");
}
return;
}
for (int i=2;i<=n;i++) {
if (!used[i]&&isp[i+now]==1) {
ans.push_back(i);
used[i]=true;
sech(i,rmn-1);
ans.pop_back();
used[i]=false;
}
}
}
以上是关于例题7-4 素数环 Prime Ring Problem UVA - 524的主要内容,如果未能解决你的问题,请参考以下文章
HDOJ 1016 Prime Ring Problem (素数环问题)
HDU 1016 Prime Ring Problem(素数环问题)
UVA - 524 Prime Ring Problem(素数环)(回溯法)