HDU1016 Prime Ring Problem

本文介绍了如何使用递归法和回溯法解决素数环问题,并提供了完整的C++代码实现。通过对不同方法的探讨,帮助读者理解算法设计原理。

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1016

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

递归法:(简单但会超时。。。)

None.gif #include  < iostream >
None.gif#include 
< vector >
None.gif#include 
< cmath >
None.gif
using   namespace  std;
None.gif
None.gif
void  swap( int &  a, int &  b)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int tmp;
InBlock.gif    tmp 
= a;
InBlock.gif    a 
= b;
InBlock.gif    b 
= tmp;
ExpandedBlockEnd.gif}

None.gif
bool  isPrime( int  num)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
for (int i=2;i<=sqrt(static_cast<double>(num));++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (num%i==0)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return false;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
return true;
ExpandedBlockEnd.gif}

None.gif
None.gif
bool  isOK( const  vector < int >&  v)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//判断是否是素数环
InBlock.gif
    bool result = true;
InBlock.gif    
for (int i=0;i<v.size()-1;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (isPrime((v[i]+v[i+1]))==false)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            result 
= false;
InBlock.gif            
break;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
if (isPrime(v[0]+v[v.size()-1])==false)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        result 
= false;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return result;
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
void  Rerange(vector < int >&  v, int  m, int  n)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if(m==n)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (isOK(v))
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
for(int j=0;j<=m;++j)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (j==m)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    cout
<<v[j]<<endl;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    cout
<<v[j]<<" ";
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
for(int i=m;i<=n;i+=2)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            swap(v[m],v[i]);
InBlock.gif            Rerange(v,m
+1,n);
InBlock.gif            swap(v[m],v[i]);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
int  main( int  argc, char *  argv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int n,i,curCase=1,tmp;
InBlock.gif    
while (cin>>n)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        cout
<<"Case "<<curCase<<":"<<endl;
InBlock.gif        vector
<int> numVector;
InBlock.gif        
if (n%2==0)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
for (i=0;i<n;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                numVector.push_back(i
+1);
ExpandedSubBlockEnd.gif            }

InBlock.gif            Rerange(numVector,
1,numVector.size()-1);
ExpandedSubBlockEnd.gif        }

InBlock.gif        cout
<<endl;
InBlock.gif        curCase
++;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

None.gif


回溯法:

None.gif #include < iostream >
None.gif#include
< cmath >
None.gif
using   namespace  std;
None.gif
None.gif
int  a[ 20 ],curCase = 0 ,n;
None.gif
None.gif
bool  isNotIn( int  num, int  end)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//是否还未在环中出现过,num是待加入环尾的元素,end是当前环尾 
InBlock.gif
    int i;
InBlock.gif    
for(i=1;i<=end-1;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if(a[i]==num)return false;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return true;
ExpandedBlockEnd.gif}

None.gif
None.gif
bool  isPrime( int  num)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//是否是素数
InBlock.gif
    for (int i=2;i<=sqrt(static_cast<double>(num));++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (num%i==0)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return false;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
return true;
ExpandedBlockEnd.gif}

None.gif
None.gif
bool  isPrimeCircl( int  num, int  end)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//是否是素数环,num是待加入环尾的元素,end是当前环尾
InBlock.gif
    if(end<n) 
InBlock.gif        
return(isPrime(num+a[end-1]));
InBlock.gif    
else //此时要考虑头尾和是否是素数
InBlock.gif
        return(isPrime(num+a[end-1])&&isPrime(num+a[1]));
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
void  output()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int k;
InBlock.gif    cout
<<a[1];
InBlock.gif    
for(k=2;k<=n;k++)
InBlock.gif        cout
<<' '<<a[k];
InBlock.gif    cout
<<endl;
ExpandedBlockEnd.gif}

None.gif
None.gif
void  back( int  i)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int k;
InBlock.gif    
for(k=1;k<=n;k++)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{  
InBlock.gif        
if(isNotIn(k,i)==true && isPrimeCircl(k,i)==true)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            a[i]
=k;
InBlock.gif            
if(i==n)
InBlock.gif                output();
InBlock.gif            
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                back(i
+1);
InBlock.gif                a[i]
=0;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
int  main()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int k;
InBlock.gif    
for(k=1;k<=20;k++)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        a[k]
=0;
ExpandedSubBlockEnd.gif    }

InBlock.gif    a[
1]=1;
InBlock.gif    
while(cin>>n)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        curCase
++;
InBlock.gif        cout
<<"Case "<<curCase<<':'<<endl;
InBlock.gif        back(
2);
InBlock.gif        cout
<<endl;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值