HDU1015 Safecracker

本文解析了一道经典的字符串组合问题,通过枚举法寻找给定字符串中符合特定数学表达式的最大字典序子集。讨论了如何通过排序和条件检查来简化搜索过程。

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

      题目罗嗦了半天,其实意思很简单,就是给定一个目标值target,再给你一个备选字符串(5~12个字符),要你在这个字符串里选5个出来,满足题中给定的等式,并且你选择的这5个字符组成的字符串必须是所有可能情况中按字典序最大的情况。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

      简单分析下就可以看出,就是一个组合问题,问题解的最大规模就是125,就是12*11*10*9*8*7,而最小规模是55,所以应该用枚举法就可以搞定。

None.gif #include  < iostream >
None.gif#include 
< string >
None.gif#include 
< vector >
None.gif
using   namespace  std;
None.gif
None.gif
bool  isOk( int  v, int  w, int  x, int  y, int  z, long   int  target)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//判断是否符合要求
InBlock.gif
    if((v-w*w+x*x*x-y*y*y*y+z*z*z*z*z)==target)
InBlock.gif       
return true;
InBlock.gif    
else
InBlock.gif       
return false;
ExpandedBlockEnd.gif}

None.gif
int  charToInt( char  ch)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return ch-'A'+1;
ExpandedBlockEnd.gif}

None.gif
void  mySort( string &  p, int  len)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {//让字符串按字母逆序排列,这样就可以很快找到最大符合要求的情况
InBlock.gif
    int i,j;
InBlock.gif    
char temp;
InBlock.gif    
for(i=0;i<len-1;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif     
dot.gif{
InBlock.gif      
for(j=0;j<len-i-1;j++)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif        
if(p[j]<p[j+1])
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif          temp
=p[j];
InBlock.gif          p[j]
=p[j+1];
InBlock.gif          p[j
+1= temp;
ExpandedSubBlockEnd.gif         }

ExpandedSubBlockEnd.gif       }

ExpandedSubBlockEnd.gif     }

ExpandedBlockEnd.gif}

None.gif
None.gif
int  main( int  argc, char *  argv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
long int target;
InBlock.gif    
int tv,tw,tx,ty,tz;
InBlock.gif    
string strTmp;
InBlock.gif    START:
InBlock.gif    
while(cin>>target>>strTmp&&!(target==0&&strTmp=="END"))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
int len = strTmp.length();
InBlock.gif        mySort(strTmp,len);
InBlock.gif        
int v,w,x,y,z;
InBlock.gif        
//下面开始用枚举法检验可能性,各个字符不能取同一个位置
InBlock.gif
        for(v=0;v<len;++v)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif              
for(w=0;w<len;++w)
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif                  
if(v!=w)
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                    
for(x=0;x<len;++x)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                          
if(x!=v&&x!=w)
ExpandedSubBlockStart.gifContractedSubBlock.gif                          
dot.gif{
InBlock.gif                              
for(y=0;y<len;++y)
ExpandedSubBlockStart.gifContractedSubBlock.gif                              
dot.gif{
InBlock.gif                                    
if(y!=v&&y!=w&&y!=x)
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
dot.gif{
InBlock.gif                                        
for(z=0;z<len;++z)
ExpandedSubBlockStart.gifContractedSubBlock.gif                                        
dot.gif{
InBlock.gif                                            
if(z!=v&&z!=w&&z!=x&&z!=y)
ExpandedSubBlockStart.gifContractedSubBlock.gif                                            
dot.gif{
InBlock.gif                                                tv 
= charToInt(strTmp[v]);
InBlock.gif                                                tw 
= charToInt(strTmp[w]);
InBlock.gif                                                tx 
= charToInt(strTmp[x]);
InBlock.gif                                                ty 
= charToInt(strTmp[y]);
InBlock.gif                                                  tz 
= charToInt(strTmp[z]);
InBlock.gif                                                
if(isOk(tv,tw,tx,ty,tz,target))
ExpandedSubBlockStart.gifContractedSubBlock.gif                                                
dot.gif{
InBlock.gif                                                       cout
<<strTmp[v]<<strTmp[w]<<strTmp[x]<<strTmp[y]<<strTmp[z]<<endl;
InBlock.gif                                                    
goto START;//遇到最大的符合要求的值,直接跳出,进入下一个
ExpandedSubBlockEnd.gif
                                                }

ExpandedSubBlockEnd.gif                                            }

ExpandedSubBlockEnd.gif                                         }

ExpandedSubBlockEnd.gif                                    }

ExpandedSubBlockEnd.gif                                }

ExpandedSubBlockEnd.gif                           }

ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif           }

InBlock.gif           cout
<<"no solution"<<endl;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值