dfs(2)

一维——穷举数所保存下标

【codevs1008】NOIP2002选数——组合的和

题目描述

已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:3+7+12=22  3+7+19=29  7+12+19=38  3+12+19=34。现在,要求你计算出和为素数共有多少种。例如上例,只有一种的和为素数:3+7+19=29)。

输入

键盘输入,格式为:n , k (1<=n<=20,k<n)x1,x2,…,xn (1<=xi<=5000000)

输出

 屏幕输出,格式为:一个整数(满足条件的种数)。

样例输入

4 3

3 7 12 19

样例输出

1

#include<iostream>

#include<cstdio>

using namespace std;

int n,k,ans=0,a[21];

bool check(int x)

{

       int i;

       for(i=2;i*i<=x;++i)

              if(x%i==0)return 0;

       return 1;

}

void dfs(int t,int s,int l)

{

       int i;

       if(t==k){if(check(s))ans++;}

       else

       for(i=l;i<=n;i++)

              dfs(t+1,s+a[i],i+1);

}

int main()

{

       int i;

       cin>>n>>k;

       for(i=1;i<=n;++i)cin>>a[i];

       dfs(0,0,1);

       cout<<ans;

       return 0;

}

 

【codevs2080】特殊的质数肋骨

题目描述

农民约翰母牛总是产生最好的肋骨。你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们。农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质数,举例来说:7 3 3 1全部肋骨上的数字 7331是质数;三根肋骨 733是质数;二根肋骨 73 是质数;当然,最后一根肋骨 7 也是质数。7331 被叫做长度 4 的特殊质数。

写一个程序对给定的肋骨的数目 N (1<=N<=8),求出所有的特殊质数。数字1不被看作一个质数。

输入

单独的一行包含N。

输出

按顺序输出长度为 N 的特殊质数,每行一个。

样例输入

4

样例输出

2333

2339

2393

2399

2939

3119

3137

3733

3739

3793

3797

5939

7193

7331

7333

7393

 

#include<iostream>

#include<math.h>

using namespace std;

int n1[4]={2,3,5,7};

int n2[4]={1,3,7,9};

int n;

bool check(int x)

{

       for(int i=2;i*i<=x;i++)

       if(x%i==0) return false;

       return true;

}

void dfs(int s,int i)

{

       int ss;

       if(i==n){cout<<s<<endl;return;}

       for(int j=0;j<4;j++){

              ss=s*10+n2[j];

              if(check(ss)) dfs(ss,i+1);

       }

}

int main()

{

       cin>>n;

       if (n==1)cout<<2<<endl<<3<<endl<<5<<endl<<7;

              else {

                     for(int i=0;i<4;i++)

                            dfs(n1[i],1);

                     }

       return 0;

}

题七 水仙花数(江苏小学信息学竞赛2010)

【问题描述】 

若一个长度为 X正整数,其各位上数字的X次方的和等于其自己,则称该数为水仙花数。

例如:153 的长度X=3,且153 = 1^3+5^3+3^3   所以, 153 是水仙花数。

现有N 个正整数(10 <= N <= 20),要求从这N个数中任取K个( 2 <=K <=4),并求出这K个数的和,统计和为水仙花数的个数。

【输入】:

本题采用文件输入:文件的第一行是二个整数N K

第二行是N个正整数(每个数均在大于等于10 、小于等于1000 之间),数与数之间的

间隔是用一个逗号(BASIC语言)或一个空格(PASCAL语言)分开。

【输出】:

输出到屏幕:一个整数,即满足条件的水仙花数的个数。

样例说明

从4个数中任取3个,仅有40,100,13的和为153,是水仙花数。

#include<iostream>

#include<cmath>

using namespace std;

int a[21],ans=0;

int n,k;

bool check(int x)

{

       int i,t=0,xx,ge,cj,sum=0;

       xx=x;

       while (xx){

              t++;xx/=10;

       }

       xx=x;

       while (xx){

              ge=xx%10;cj=1;

              for (i=1;i<=t;++i){

                     cj*=ge;

              }

              sum+=cj;

              xx/=10;

       }

       if(sum==x)return 1;

              else return 0;

}

void search(int t,int s,int l)

{

       if(t==k){if(check(s))ans++;}

              else

              for(int i=l;i<=n;i++)

                     search(t+1,s+a[i],i+1);

}

int main()

{

    cin>>n>>k;

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

       cin>>a[i];

    search(0,0,1);

    cout<<ans;

    return 0;

}

题五 优美连接(江苏小学信息学竞赛2011)

【问题描述】 

给出n个2位整数(1≤n≤10),将这n个数拼成一个长2n位长整数:y=x1 x2 x3……x2n

然后进行计算:    d=│x1-x2│+│x2-x3│+….+ │x2n-1-x2n│

问题:当n个数给出之后,找出一种拼接方法,使d最小。

例如:n=3 时,三个数分别为: 26,17,34

拼接方法有:

    26 17 34    d=│2-6│+│6-1│+│1-7│+│7-3│+│3-4│=20

    26 34 17     d=│2-6│+│6-3│+│3-4│+│4-1│+│1-7│=17

    ……

    17 34 26     d=│1-7│+│7-3│+│3-4│+│4-2│+│2-6│=17

其中最小d为17

【输入】

 本题采用文件输入,输入文件第一行一个整数n,第二行n个整数,

【输出】 

显示在屏幕上,一个整数,即最小的d

【样例】:

输入:

4

13 59 42 88

输出:

12

 

#include<iostream>

#include<cmath>

using namespace std;

int a[21],b[21],used[21],ans=10000;

int n,k;

void check()

{

       int x,y,i,sum=0;

       x=b[1]/10;y=b[1]%10;

       sum=abs(x-y);

       for(i=2;i<=n;++i){

              x=y;y=b[i]/10;

              sum+=abs(x-y);

              x=y;y=b[i]%10;

              sum+=abs(x-y);

       }

       if(sum<ans)ans=sum;

}

void dfs(int t)

{

       if(t==n){check();return;}

              else

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

                     if(a[used[i]])continue;

                     b[t+1]=a[i];

                     used[i]=1;

                     dfs(t+1);

                     used[i]=0;

              }

}

int main()

{

    cin>>n;

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

       cin>>a[i];

    dfs(0);

    cout<<ans;

    return 0;

}

【hdu 1181】变形课

http://acm.hdu.edu.cn/showproblem.php?pid=1181

Problem Description

呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规律:如果咒语是以a开头b结尾的一个单词,那么它的作用就恰好是使A物体变成B物体.
Harry已经将他所会的所有咒语都列成了一个表,他想让你帮忙计算一下他是否能完成老师的作业,将一个B(ball)变成一个M(Mouse),你知道,如果他自己不能完成的话,他就只好向Hermione请教,并且被迫听一大堆好好学习的道理.

Input

测试数据有多组。每组有多行,每行一个单词,仅包括小写字母,是Harry所会的所有咒语.数字0表示一组输入结束.

Output

如果Harry可以完成他的作业,就输出"Yes.",否则就输出"No."(不要忽略了句号)

Sample Input

so

soon

river

goes

them

got

moon

begin

big

0

Sample Output

Yes.

Hint

Hint

Harry 可以念这个咒语:"big-got-them".

 

#include<cstdio>

#include<cstring>

using namespace std;

int v[105],t,kase,k;

struct bxk

{

       int l,r;

}x[105];//保存每个元素

void dfs(int k)

{

       if(x[k].r=='m'){//判断终止

              kase=1;

              return;

              }

       for(int i=0;i<t;++i){//查找....

              if(!v[i]&&x[i].l==x[k].r){//找到

                     v[i]=1;//标记..

                     dfs(i);//递归搜索

                     v[i]=0;//取消标记

                     }

              }

}

int main()

{

       char s[1005];

       while(gets(s)){//这个格式特别不好,注意控制

              t=0;memset(v,0,sizeof(v));

              while(s[0]!='0'){

                     int len=strlen(s);

                     x[t].l=s[0];x[t].r=s[len-1];//只要两端的元素

                     gets(s);

                     ++t;

                     }

              kase=0;

              for(int i=0;i<t;++i){

                     if(x[i].l=='b'){

                            v[i]=1;

                            dfs(i);//找到后搜索....

                            if(kase){

                                   break;//判断跳出

                                   }

                            }

                     }

              if(kase)printf("Yes.\n");

                     else printf("No.\n");

              }

       return 0;

}

 

【hdu 1342】Lotto——n个数中取六个的组合

 

Problem Description

In a Lotto I have ever played, one has to select 6 numbers from the set {1,2,...,49}. A popular strategy to play Lotto - although it doesn't increase your chance of winning - is to select a subset S containing k (k>6) of these 49 numbers, and then play several games with choosing numbers only from S. For example, for k=8 and S = {1,2,3,5,8,13,21,34} there are 28 possible games: [1,2,3,5,8,13], [1,2,3,5,8,21], [1,2,3,5,8,34], [1,2,3,5,13,21], ... [3,5,8,13,21,34].

Your job is to write a program that reads in the number k and the set S and then prints all possible games choosing numbers only from S.

Input

The input file will contain one or more test cases. Each test case consists of one line containing several integers separated from each other by spaces. The first integer on the line will be the number k (6 < k < 13). Then k integers, specifying the set S, will follow in ascending order. Input will be terminated by a value of zero (0) for k.

Output

For each test case, print all possible games, each game on one line. The numbers of each game have to be sorted in ascending order and separated from each other by exactly one space. The games themselves have to be sorted lexicographically, that means sorted by the lowest number first, then by the second lowest and so on, as demonstrated in the sample output below. The test cases have to be separated from each other by exactly one blank line. Do not put a blank line after the last test case.

Sample Input

7 1 2 3 4 5 6 7

8 1 2 3 5 8 13 21 34

0

Sample Output

1 2 3 4 5 6

1 2 3 4 5 7

1 2 3 4 6 7

1 2 3 5 6 7

1 2 4 5 6 7

1 3 4 5 6 7

2 3 4 5 6 7

 

1 2 3 5 8 13

1 2 3 5 8 21

1 2 3 5 8 34

1 2 3 5 13 21

1 2 3 5 13 34

1 2 3 5 21 34

1 2 3 8 13 21

1 2 3 8 13 34

1 2 3 8 21 34

1 2 3 13 21 34

1 2 5 8 13 21

1 2 5 8 13 34

1 2 5 8 21 34

1 2 5 13 21 34

1 2 8 13 21 34

1 3 5 8 13 21

1 3 5 8 13 34

1 3 5 8 21 34

1 3 5 13 21 34

1 3 8 13 21 34

1 5 8 13 21 34

2 3 5 8 13 21

2 3 5 8 13 34

2 3 5 8 21 34

2 3 5 13 21 34

2 3 8 13 21 34

2 5 8 13 21 34

3 5 8 13 21 34

Source

University of Ulm Local Contest 1996

题目大意

从k个数中取出六个数的组合。

#include<stdio.h>

#include<string.h>

int x[105],y[105],z[105],n,kase;

void dfs(int v)

{

       if(v==6){//控制什么时候输出

              int i;

              for(i=0;i<5;++i)printf("%d ",x[i]);

              printf("%d\n",x[i]);//注意每行最后没有空格

              return;

              }

       for(int i=0;i<n;++i){//这个循环递归,相当于多层循环...

              if(!z[i]){

                     z[i]=1;//标记上

                     x[v]=y[i];

                     if(v==0||(x[v-1]<x[v])){//这个就是限定,只打印排列

                            dfs(v+1);//满足以上条件,就继续递归循环

                            }

                     z[i]=0;//取消标记

                     }

              }

}

int main()

{

       while(scanf("%d",&n),n){

              memset(z,0,sizeof(z));//.这个不能少

              if(kase++)printf("\n");//输出的空行注意啊

              for(int i=0;i<n;++i)scanf("%d",&y[i]);//输入...

              dfs(0);//调用输出....

              }

       return 0;

}

【hdu1015】Safecracker——排列

Problem Description

"The item is locked in a Klein safe behind a painting in the second-floor library. Klein safes are extremely rare; most of them, along with Klein and his factory, were destroyed in World War II. Fortunately old Brumbaugh from research knew Klein's secrets and wrote them down before he died. A Klein safe has two distinguishing features: a combination lock that uses letters instead of numbers, and an engraved quotation on the door. A Klein quotation always contains between five and twelve distinct uppercase letters, usually at the beginning of sentences, and mentions one or more numbers. Five of the uppercase letters form the combination that opens the safe. By combining the digits from all the numbers in the appropriate way you get a numeric target. (The details of constructing the target number are classified.) To find the combination you must select five letters v, w, x, y, and z that satisfy the following equation, where each letter is replaced by its ordinal position in the alphabet (A=1, B=2, ..., Z=26). The combination is then vwxyz. If there is more than one solution then the combination is the one that is lexicographically greatest, i.e., the one that would appear last in a dictionary."

v - w^2 + x^3 - y^4 + z^5 = target

"For example, given target 1 and letter set ABCDEFGHIJKL, one possible solution is FIECB, since 6 - 9^2 + 5^3 - 3^4 + 2^5 = 1. There are actually several solutions in this case, and the combination turns out to be LKEBA. Klein thought it was safe to encode the combination within the engraving, because it could take months of effort to try all the possibilities even if you knew the secret. But of course computers didn't exist then."

=== Op tech directive, computer division, 2002/11/02 12:30 CST ===

"Develop a program to find Klein combinations in preparation for field deployment. Use standard test methodology as per departmental regulations. Input consists of one or more lines containing a positive integer target less than twelve million, a space, then at least five and at most twelve distinct uppercase letters. The last line will contain a target of zero and the letters END; this signals the end of the input. For each line output the Klein combination, break ties with lexicographic order, or 'no solution' if there is no correct combination. Use the exact format shown below."

Sample Input

1 ABCDEFGHIJKL

11700519 ZAYEXIWOVU

3072997 SOUGHT

1234567 THEQUICKFROG

0 END

Sample Output

LKEBA

YOXUZ

GHOST

no solution

题意:

给定一个长度为5……12个不同字符组成的字符串,从中选取5个,设为v,w,x,y,z,要满足等式:v-w^2+x^3-y^4+z^5=target,现在给出字符串和target,求满足该条件的5个字符(字典序要最大)

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<algorithm>

using namespace std;

int target,kase,vis[105];

char s[105],ans[15];

bool fun(char a[])//求解是否满足等式

{

       int v=a[0]-'A'+1,w=a[1]-'A'+1,x=a[2]-'A'+1,y=a[3]-'A'+1,z=a[4]-'A'+1;

       return target==(v-w*w+x*x*x-y*y*y*y+z*z*z*z*z);

}

bool dfs(int j)

{

       if(j==5){//五个数的排列

              if(fun(ans))return 1;

              return 0;

       }

       for(int k=0;s[k];++k){//循环,递归,回溯

              if(!vis[k]){

                     vis[k]=1;

                     ans[j]=s[k];

                     if(dfs(j+1))return 1;

                     vis[k]=0;

              }

       }

}

bool cmp(char a,char b)

{

       return a>b;

}

int main()

{

       //freopen("shuju.txt","r",stdin);

       while(~scanf("%d%s",&target,s)){

              memset(ans,0,sizeof(ans));

              memset(vis,0,sizeof(vis));

              if(target==0&&strcmp(s,"END")==0)break;

              sort(s,s+strlen(s),cmp);

              if(!dfs(0))printf("no solution\n");

                     else printf("%s\n",ans);

              }

       return 0;

}

【hdu1027】Ignatius and the Princess II

Problem Description

Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5166 says, "I have three question for you, if you can work them out, I will release the Princess, or you will be my dinner, too." Ignatius says confidently, "OK, at last, I will save the Princess."

"Now I will show you the first problem." feng5166 says, "Given a sequence of number 1 to N, we define that 1,2,3...N-1,N is the smallest sequence among all the sequence which can be composed with number 1 to N(each number can be and should be use only once in this problem). So it's easy to see the second smallest sequence is 1,2,3...N,N-1. Now I will give you two numbers, N and M. You should tell me the Mth smallest sequence which is composed with number 1 to N. It's easy, isn't is? Hahahahaha......"

Can you help Ignatius to solve this problem?

Input

The input contains several test cases. Each test case consists of two numbers, N and M(1<=N<=1000, 1<=M<=10000). You may assume that there is always a sequence satisfied the BEelzebub's demand. The input is terminated by the end of file.

Output

For each test case, you only have to output the sequence satisfied the BEelzebub's demand. When output a sequence, you should print a space between two numbers, but do not output any spaces after the last number.

Sample Input

6 4

11 8

Sample Output

1 2 3 5 6 4

1 2 3 4 5 6 7 9 8 11 10

这道题的意思是输出n个数全排列的第m个全排列。

 

#include<cstdio>

#include<cstring>

using namespace std;

int n,m,cnt,kase,vis[1005],ans[1005];

void dfs(int i)

{

       if(kase||i==n+1){

              ++cnt;

              if(cnt==m)kase=1;

              return;

       }

       for(int k=1;k<=n;++k){

              if(!vis[k]){

                     vis[k]=1;

                     ans[i]=k;

                     dfs(i+1);

                     if(kase)return;

                     vis[k]=0;

              }

       }

}

int main()

{

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

              memset(vis,0,sizeof(vis));

              cnt=kase=0;

              dfs(1);

              printf("%d",ans[1]);

              for(int i=2;i<=n;++i)printf(" %d",ans[i]);

              printf("\n");

       }

       return 0;

}

【hdu1501】【poj2192】Zipper

Problem Description

Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.

For example, consider forming "tcraete" from "cat" and "tree":

String A: cat

String B: tree

String C: tcraete

As you can see, we can form the third string by alternating characters from the two strings. As a second example, consider forming "catrtee" from "cat" and "tree":

String A: cat

String B: tree

String C: catrtee

Finally, notice that it is impossible to form "cttaree" from "cat" and "tree".

Input

The first line of input contains a single positive integer from 1 through 1000. It represents the number of data sets to follow. The processing for each data set is identical. The data sets appear on the following lines, one data set per line.

For each data set, the line of input consists of three strings, separated by a single space. All strings are composed of upper and lower case letters only. The length of the third string is always the sum of the lengths of the first two strings. The first two strings will have lengths between 1 and 200 characters, inclusive.

Output

For each data set, print:

Data set n: yes

if the third string can be formed from the first two, or

Data set n: no

if it cannot. Of course n should be replaced by the data set number. See the sample output below for an example.

Sample Input

3

cat tree tcraete

cat tree catrtee

cat tree cttaree

Sample Output

Data set 1: yes

Data set 2: yes

Data set 3: no

Source

Pacific Northwest 2004 

 

#include<stdio.h>

#include<string.h>

const int maxn=205;

char a[maxn],b[maxn],c[maxn*2];

bool vis[maxn][maxn];

bool ok(int la,int lena,int lb,int lenb)

{

       if(la==lena&&lb==lenb)return 1;

       int kase=0;

       if((la<lena||lb<lenb)&&!vis[la][lb]){

              vis[la][lb]=1;

              if(a[la]==c[la+lb])kase=ok(la+1,lena,lb,lenb);

              if(b[lb]==c[la+lb])kase=kase||ok(la,lena,lb+1,lenb);

              }

       return kase;

}

int main()

{

       int t,i,j,k,l;

       scanf("%d",&t);

       for(i=1;i<=t;i++){

              memset(vis,0,sizeof(vis));

              scanf("%s%s%s",a,b,c);

              printf("Data set %d: ",i);

              printf("%s\n",ok(0,strlen(a),0,strlen(b))?"yes":"no");

              }

       return 0;

}

转载于:https://www.cnblogs.com/aclsoyne/p/7868449.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:DFS是深度优先搜索的缩写,它是一种图遍历算法。DFS的实现可以使用栈来模拟,代码和BFS基本相同,只需要将BFS中的队列改为栈,将pop(0)改为pop()即可。下面是一个使用DFS实现的Python代码示例: ```python def DFS(graph, s): stack = \[\] # 用栈来实现DFS stack.append(s) # 将起始点加入栈中 seen = \[\] # 用来保存已经访问过的节点 seen.append(s) while len(stack) > 0: vertex = stack.pop() # 弹出栈顶元素 nodes = graph\[vertex\] for node in nodes: if node not in seen: stack.append(node) seen.append(node) print(vertex) # 打印当前访问的节点 graph = { "A": \["B", "C"\], "B": \["A", "C", "D"\], "C": \["A", "B", "D", "E"\], "D": \["B", "C", "E", "F"\], "E": \["C", "D"\], "F": \["D"\] } DFS(graph, "A") ``` 引用\[2\]:DFS是深度优先搜索的缩写,它是一种图遍历算法。DFS的实现可以使用栈来模拟,代码和BFS基本相同,只需要将BFS中的队列改为栈,将pop(0)改为pop()即可。下面是一个使用DFS实现的Python代码示例: ```python def DFS(graph, s): stack = \[\] # 用栈来实现DFS stack.append(s) # 将起始点加入栈中 seen = \[\] # 用来保存已经访问过的节点 seen.append(s) while len(stack) > 0: vertex = stack.pop() # 弹出栈顶元素 nodes = graph\[vertex\] for node in nodes: if node not in seen: stack.append(node) seen.append(node) print(vertex) # 打印当前访问的节点 graph = { "A": \["B", "C"\], "B": \["A", "C", "D"\], "C": \["A", "B", "D", "E"\], "D": \["B", "C", "E", "F"\], "E": \["C", "D"\], "F": \["D"\] } DFS(graph, "A") ``` 综上所述,以上是两个使用DFS实现的Python代码示例。它们的原理是通过栈来模拟深度优先搜索,从起始点开始,一直沿着一条路径走到底,直到无路可走再回溯。在遍历过程中,使用一个列表来保存已经访问过的节点,以避免重复访问。 #### 引用[.reference_title] - *1* *2* *3* [Python BFS和DFS算法](https://blog.csdn.net/qq_43540763/article/details/115144191)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值