POJ 1011(Sticks)解题纠错
2011-03-27 20:57
351 查看
以下来自http://topic.csdn.net/u/20110324/20/f62e1942-a2bc-4ee4-b015-98e2102cd46c.html?seed=1228193625&r=72409442#r_72409442
POJ报的错误是超时,原因可能是有些用例陷入死循环,如:
2
1 1
5
3 7 11 13 17
3
2 4 8
经检查,有以下问题:
(1)isUsed只做了一次初始化;
(2)匹配成功一根木棒后没有从头开始搜索;
(3)如果后面不成功,还在继续搜索。
以下修改AC:
#include<iostream> #include<cstdlib> #include<map> using namespace std; int everyLength[64];//输入的每一节小木棍的长度 bool isUsed[64];//跟踪每个小木棍是否被使用 map<int,int> numPost;//记录相同长度小木棍的最后一个位置 int groupNum,groupLength;//记录有多少根棍,每个棍多长 //compare函数,用于qsort函数中使用。 int compare(const void *n1,const void *n2){ return(*((int*)n2)-*((int*)n1)); } //参数为原始木棒长度,小木棒总个数,上一次取木棒的位置 bool dealwith(int minlength,int number,int lastnote){ //开始循环找木棒拼会原始木棒,当然从最大的那根开始 for(int i=lastnote+1;i<number;++i){ //首先看是否被使用过 if(isUsed[i]){ //如果当前小木棍大于所需要的长度,那么跳过所有该长度的小木棍 if(minlength-everyLength[i]<0){ i=numPost[everyLength[i]]; continue; } //如果成功拼出一个木棍 else if(minlength-everyLength[i]==0){ isUsed[i]=false;//标记该木棍被使用了。 --groupNum; //需要拼接的小木棍少一个 //如果只剩下一个木棍,则一定成功了。 if(groupNum==1) return true; if(dealwith(groupLength,number,0))//如果后面的木棍返回成功,说明全部成功了 return true; else{ //如果后面的木棍拼接不成功,那么说明这个木棍是有问题的 ++groupNum; //将为拼接的原始木棍数+1 isUsed[i]=true; //使用的小木棍设置为未使用 i=numPost[everyLength[i]]; //并且这个小木棍一样长度的木棍都不适用 continue; } } else{ //如果还是不够长度,那么继续 isUsed[i]=false; //设置该木棍被使用 if(dealwith(minlength-everyLength[i],number,i)) //如果返回成功,则成功拼接 return true; else{ isUsed[i]=true; //如果不成功,那么该木棍不可以使用 if(minlength==groupLength) //并且,如果这是一个原始木棍第一个最长小木棍拼接处返回的, return false; //则说明这个长木棍没办法和下面的小木棍结合,故直接返回上一根拼接好的木棍 i=numPost[everyLength[i]]; } } } } return false; } int main(){ int sticksNum; while(cin>>sticksNum){ if(sticksNum==0) break; int i,sum(0); for(i=0;i<sticksNum;++i){ cin>>everyLength[i]; isUsed[i]=true; sum+=everyLength[i]; } qsort(everyLength,i,sizeof(int),compare);//按照从大到小排列数据 for(int j=0;j<i;++j) numPost[everyLength[j]]=j;//收集每个相同长度小木棒的最后一个的位置 //找到能被木棒之和整除的数据。 for(int j=everyLength[0]+1;;++j){ if(sum%j==0){ groupLength=j;//记录下当前最小原始木棒长度 groupNum=sum/j;//记录下此长度下有多少个木棒 if(dealwith(j,i,-1)){//若这些小木棒可以拼成原始木棒,则打印。 cout<<j<<endl; break; } } } } return 0; }
POJ报的错误是超时,原因可能是有些用例陷入死循环,如:
2
1 1
5
3 7 11 13 17
3
2 4 8
经检查,有以下问题:
(1)isUsed只做了一次初始化;
(2)匹配成功一根木棒后没有从头开始搜索;
(3)如果后面不成功,还在继续搜索。
以下修改AC:
#include<iostream> #include<cstdlib> #include<map> using namespace std; int everyLength[64];//输入的每一节小木棍的长度 bool isUsed[64];//跟踪每个小木棍是否被使用 map<int,int> numPost;//记录相同长度小木棍的最后一个位置 int groupNum,groupLength;//记录有多少根棍,每个棍多长 //compare函数,用于qsort函数中使用。 int compare(const void *n1,const void *n2){ return(*((int*)n2)-*((int*)n1)); } //参数为原始木棒长度,小木棒总个数,上一次取木棒的位置 bool dealwith(int minlength,int number,int lastnote){ //开始循环找木棒拼会原始木棒,当然从最大的那根开始 for(int i=lastnote+1;i<number;++i){ //首先看是否被使用过 if(isUsed[i]){ //如果当前小木棍大于所需要的长度,那么跳过所有该长度的小木棍 if(minlength-everyLength[i]<0){ i=numPost[everyLength[i]]; continue; } //如果成功拼出一个木棍 else if(minlength-everyLength[i]==0){ isUsed[i]=false;//标记该木棍被使用了。 --groupNum; //需要拼接的小木棍少一个 //如果只剩下一个木棍,则一定成功了。 if(groupNum<=1)//if(groupNum==1) return true; //if(dealwith(groupLength,number,0))//如果后面的木棍返回成功,说明全部成功了 if(dealwith(groupLength,number,-1))//如果后面的木棍返回成功,说明全部成功了 return true; else{ //如果后面的木棍拼接不成功,那么说明这个木棍是有问题的 ++groupNum; //将为拼接的原始木棍数+1 isUsed[i]=true; //使用的小木棍设置为未使用 //i=numPost[everyLength[i]]; //并且这个小木棍一样长度的木棍都不适用 return false;//continue; } } else{ //如果还是不够长度,那么继续 isUsed[i]=false; //设置该木棍被使用 if(dealwith(minlength-everyLength[i],number,i)) //如果返回成功,则成功拼接 return true; else{ isUsed[i]=true; //如果不成功,那么该木棍不可以使用 if(minlength==groupLength) //并且,如果这是一个原始木棍第一个最长小木棍拼接处返回的, return false; //则说明这个长木棍没办法和下面的小木棍结合,故直接返回上一根拼接好的木棍 i=numPost[everyLength[i]]; } } } } return false; } int main(){ int sticksNum; while(cin>>sticksNum){ if(sticksNum==0) break; int i,sum(0); for(i=0;i<sticksNum;++i){ cin>>everyLength[i]; isUsed[i]=true; sum+=everyLength[i]; } qsort(everyLength,i,sizeof(int),compare);//按照从大到小排列数据 for(int j=0;j<i;++j) numPost[everyLength[j]]=j;//收集每个相同长度小木棒的最后一个的位置 //找到能被木棒之和整除的数据。 for(int j=everyLength[0];j<=sum;++j){//for(int j=everyLength[0]+1;;++j){ if(sum%j==0){ groupLength=j;//记录下当前最小原始木棒长度 groupNum=sum/j;//记录下此长度下有多少个木棒 for(int k=0;k<sticksNum;++k)isUsed[k]=true; if(dealwith(j,i,-1)){//若这些小木棒可以拼成原始木棒,则打印。 cout<<j<<endl; break; } } } } return 0; }
相关文章推荐
- POJ 1011 Sticks 解题报告
- POJ 1011 Sticks 解题报告
- ACM poj 1011 Sticks解题报告源代码【转】
- poj 1011 Sticks解题报告【DFS+剪枝】
- POJ 1011 STICKS 搜索 剪枝
- POJ 1011 Sticks
- POJ 1011 Sticks(深搜+剪枝)
- poj 1011 :Sticks (dfs+剪枝)
- hdu 1455/poj 1011 Sticks(DFS剪枝神题)
- DFS(剪枝) POJ 1011 Sticks
- POJ 1011 Sticks
- poj 1011 Sticks
- POJ 1011 Sticks (dfs + 厉害的剪枝)
- poj dfs相关之1011 Sticks
- poj1011 Sticks
- POJ 1011 / UVA 307 Sticks
- POJ 1065 Wooden Sticks 解题报告-用动态规划方法解决(LIS变式)
- POJ 1011--Sticks
- [DFS+剪枝]POJ 1011/HDOJ 1455/HOJ 1049 Sticks
- POJ1011 Sticks 深度优先搜索+剪枝