hdu 1342+hdu 2660+hdu 2266+hdu 1704+hdu 1627+hdu 1539

几道搜索水题,搜索要点就是不断剪枝,必要时还要不断恢复路径。

慢慢体会递归的强大!!!

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1342

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 #define MAXN 55

 6 int num[MAXN];

 7 int path[MAXN];

 8 int k,len;

 9 

10 void dfs(int x,int cnt){

11     path[len++]=num[x];

12     if(cnt==6){

13         printf("%d",path[0]);

14         for(int i=1;i<len;i++)printf(" %d",path[i]);

15         puts("");

16         return ;

17     }

18     for(int i=x+1;i<=k;i++){

19         dfs(i,cnt+1);

20         len--;

21     }

22 }

23 

24 int main(){

25     int t=0;

26     while(~scanf("%d",&k)&&k){

27         if(t++)puts("");

28         for(int i=1;i<=k;i++)scanf("%d",&num[i]);

29         for(int i=1;i<=k;i++){

30             len=0;

31             dfs(i,1);

32         }

33     }

34     return 0;

35 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2660

这道题也可以用背包解。

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 #define MAXN 22

 6 struct Node{

 7     int v,w;

 8 }node[MAXN];

 9 

10 int W,n,k,ans;

11 

12 void dfs(int i,int value,int weight,int count){

13     if(count==k){

14         ans=max(ans,value);

15         return ;

16     }

17     for(int j=i+1;j<=n;j++){

18         if(weight+node[j].w<=W)dfs(j,value+node[j].v,weight+node[j].w,count+1);

19     }

20 }

21 

22 int main(){

23     int _case;

24     scanf("%d",&_case);

25     while(_case--){

26         scanf("%d%d",&n,&k);

27         for(int i=1;i<=n;i++){

28             scanf("%d%d",&node[i].v,&node[i].w);

29         }

30         scanf("%d",&W);

31         ans=0;

32         for(int i=1;i<=n;i++){

33             if(node[i].w<=W)dfs(i,node[i].v,node[i].w,1);

34         }

35         printf("%d\n",ans);

36     }

37     return 0;

38 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2266

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<string>

 5 #include<cmath>

 6 using namespace std;

 7 typedef long long ll;

 8 

 9 #define MAXN 14

10 ll sum,cnt;

11 int len;

12 char str[MAXN];

13 

14 //递归的强大!!!

15 void dfs(int pos,ll s){

16     if(pos==len&&s==sum){

17         cnt++;

18         return ;

19     }

20     ll tmp=0;

21     for(int i=pos;i<len;i++){

22         tmp=tmp*(ll)10+str[i]-'0';

23         dfs(i+1,s+tmp);

24         if(pos!=0)dfs(i+1,s-tmp);//不知为什么,pos改成i就错了。

25     }

26 }

27 

28 int main(){

29     while(~scanf("%s",str)){

30         scanf("%I64d",&sum);

31         cnt=0,len=strlen(str);

32         dfs(0,0);

33         printf("%d\n",cnt);

34     }

35     return 0;

36 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1704

这道题也可以用传递闭包来做。

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<vector>

 5 using namespace std;

 6 #define MAXN 555

 7 vector<int>vt[MAXN];

 8 int n,m;

 9 

10 bool dfs(int x,int y){

11     for(int i=0;i<vt[x].size();i++){

12         int u=vt[x][i];

13         if(u==y)return true;

14         if(dfs(u,y))return true;

15     }

16     return false;

17 }

18 

19 int main(){

20     int _case,u,v;

21     scanf("%d",&_case);

22     while(_case--){

23         scanf("%d%d",&n,&m);

24         for(int i=1;i<=n;i++)vt[i].clear();

25         for(int i=1;i<=m;i++){

26             scanf("%d%d",&u,&v);

27             vt[u].push_back(v);

28         }

29         int cnt=0;

30         for(int i=1;i<=n;i++){

31             for(int j=i+1;j<=n;j++){

32                 if(!(dfs(i,j)||dfs(j,i)))cnt++;

33             }

34         }

35         printf("%d\n",cnt);

36     }

37     return 0;

38 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1627

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 #define MAXN 111

 6 int path[MAXN];

 7 int n,l,cnt;

 8 

 9 bool dfs(int cur){

10     if(n==cnt){

11         int k=0,num=0;

12         for(int i=0;i<cur;i++){

13             if(k==4&&num!=16){printf(" ");k=0;}

14             if(num==16){puts("");num=0,k=0;}

15             printf("%c",path[i]+'A');

16             k++;

17             if(k==4)num++;

18         }

19         puts("");

20         printf("%d\n",cur);

21         return true;

22     }

23     for(int i=0;i<l;i++){

24         path[cur]=i;

25         bool flag=false;

26         for(int j=1;j<=(cur+1)/2;j++){

27             flag=true;

28             for(int k=0;k<j;k++){

29                 if(path[cur-k]!=path[cur-j-k]){flag=false;break;}

30             }

31             if(flag)break;

32         }

33         if(flag)continue;

34         cnt++;

35         if(dfs(cur+1))return true;

36     }

37     return false;

38 }

39 

40 

41 int main(){

42     while(~scanf("%d%d",&n,&l)){

43         if(n==0&&l==0)break;

44         memset(path,-1,sizeof(path));

45         cnt=0;

46         dfs(0);

47     }

48     return 0;

49 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1539

对这道题略无语,测试数据都说了不超过6位,我开了11位,wa无数次,最后搞了个22位的过了。。。

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 using namespace std;

 5 #define MAXN 22//不是说测试数据不超过6位吗!!!一开始搞了个11的还过不了!!!!

 6 char str[MAXN];

 7 int n,len,relen,ans,l,tag;

 8 int path[MAXN];

 9 int repath[MAXN];

10 

11 //递归+路径保存!!!

12 void dfs(int pos,int sum){

13     if(sum>n)return ;

14     if(pos==len){

15         if(sum<=n&&sum>=ans){

16             if(sum==ans)tag=2;//有多个最接近的值,就rejected

17             else {

18                 ans=sum,relen=0,tag=1;

19                 for(int i=0;i<l;i++)repath[relen++]=path[i];

20             }

21         }

22         return ;

23     }

24     int tmp=0;

25     for(int i=pos;i<len;i++){

26         tmp=tmp*10+str[i]-'0';

27         path[l++]=tmp;

28         dfs(i+1,sum+tmp);

29         l--;

30     }

31 }

32 

33 

34 

35 int main(){

36     while(~scanf("%d%s",&n,str)){

37         if(n==0&&str[0]=='0')break;

38         len=strlen(str);

39         ans=0,l=0,tag=0;

40         memset(path,0,sizeof(path));

41         memset(repath,0,sizeof(repath));

42         dfs(0,0);

43         if(tag==0)puts("error");//都大于n就是error了。

44         else if(tag==2)puts("rejected");

45         else {

46             printf("%d",ans);

47             for(int i=0;i<relen;i++)printf(" %d",repath[i]);

48             printf("\n");

49         }

50     }

51     return 0;

52 }

 

你可能感兴趣的:(HDU)