标签:soj soj1093 soj1093伊拉克 回缩
背景:这题做了大概五个小时,每次都在标记上出错。
思路:回溯,我先把军舰的长度按照由长到短依次排列,然后依次检索,特别注意变量l的使用,正是这个变量的使用,我的一段混乱代码才可以过。
题目中的数据很容易过,如果实在找不出错误,又不知道如何出数据,可以把第一组和第二组数据结合起来(一般人我不告诉他,哈哈)。代码如下,请自行理解。
学习:回溯算法:从一条路往前走,能进则进,不能进则退回来,换一条路再试。
#include <iostream> #include <algorithm> #include <cstring> using namespace std; int shuchu[12][102],junjian1[102],jilu[12],ok,m; int junjian[102],duiwu[12],l; bool paixu(int a,int b) { return a>b; } void judge1(int k,int i,int j,int sum,int d,int j1) { if(ok||k>d) return; junjian1[j]=1; shuchu[i][sum]=junjian[j]; if(i==1&&sum==1) l=j; if(k==d) {ok=1;jilu[i]=sum;return;} if(k<d) { for(;j<=m;j++) { if(ok) return; if(junjian1[j]) continue; if(!junjian1[j]) judge1(k+junjian[j],i,j,sum+1,d,j1); if(!ok) junjian1[j]=0; } } } void judge(int junjian[],int d,int m,int n,int i,int k) { for(int j=k;j<=m;j++) { if(junjian1[j]) continue; if(!junjian1[j]) { judge1(junjian[j],i,j,1,d,j); if(!ok) junjian1[j]=0; } if(ok) return; } } int main(void) { int n; while(cin>>m>>n&&m&&n) { memset(junjian1,0,sizeof(junjian1)); memset(shuchu,0,sizeof(shuchu)); memset(jilu,0,sizeof(jilu)); memset(junjian,0,sizeof(junjian)); memset(duiwu,0,sizeof(duiwu)); for(int i=1;i<=m;i++) cin>>junjian[i]; for(int j=1;j<=n;j++) cin>>duiwu[j]; sort(junjian+1,junjian+m+1,paixu); for(int i1=1;i1<=n;i1++) { ok=0; judge(junjian,duiwu[i1],m,n,i1,1); if(!ok) { int k1=l+1; i1=1; memset(shuchu,0,sizeof(shuchu)); memset(jilu,0,sizeof(jilu)); memset(junjian1,0,sizeof(junjian1)); judge(junjian,duiwu[i1],m,n,i1,k1); } } for(int i2=1;i2<=n;i2++) { cout<<jilu[i2]; for(int j=1;j<=jilu[i2];j++) { cout<<' '<<shuchu[i2][j]; } cout<<endl; } } return 0; }
标签:soj soj1093 soj1093伊拉克 回缩
原文地址:http://blog.csdn.net/qiweigo/article/details/44025857