TOJ--1343--dfs

先碎碎念一段:~

  今天凌晨熬夜看个比赛... 桑巴军团 太让我失望了 华丽与你们无缘了。。。  竟然还要靠那个 不存在 的点球.......

  shame

  今晚 有 荷兰打西班牙 虽然两个球队 都无爱  西班牙的踢球风格不喜欢.....  荷兰 橙色 还是很震撼的......... 他们这也算上届世界杯决赛小组赛就碰到。。。
OK:

  我们上题吧  这是一个dfs题

    touch me

题目大意就是:

  给你一个n 和m个数据的数组 用该数组内的元素进行相加得到n 输出所有的可能情况

  你要注意 下 这句话的含义  A number can be used within a sum as many times as it appears in the list, and a single number counts as a sum

  就是说 一个数字可以被使用的次数最多就是它在数组中出现的次数  一个数字自己可以单独做为和 只要与n相等

  还有很重要的一点: The numbers within each sum must appear in nonincreasing order   就是数组在你输入的时候就要确定是按递减输入的

  那么 就省得我们自己去排序了

我的思路:dfs它   递归的出口条件自然是  我们不断搜索 得到的sum>n那就结束这次搜索 如果sum==n 那就输出这个sum中各个元素的值 它通过数组来进行保存   这边的关键是 对于重复元素的剪枝   相当于我给你一组数据 4 4 2 2 1 1

你的输出结果 应该是 2+2  2+1+1  如果你没处理好这两个2之间的关系 那么 你将会输出 2+2  2+1+1  2+1+1

OK 这就是本题的重点。  我通过下面2种方法来实现它

对于第1种 我开的 bool vis[]数组的位置很重要  它必须开在dfs函数中 而不能当作全局变量 因为这样会影响其它的递归 它们是各自独立的

第2种 就直接通过一个间接变量 保存了下 我本次递归开始的头元素的值 然后进行判断。。。

接下来 上代码......

 1 // TOJ 1343 数字 降序 出现
 2 // 给你一个n 和m个数据的数组 用该数组内的元素进行相加得到n 输出所有的可能情况
 3
 4 #include <iostream>
 5 #include <cstring>
 6 using namespace std;
 7
 8 int n , m;
 9 int arr[15];
10 int temp[1100];
11 bool flag;
12
13
14 void dfs( int sum , int pos , int cnt )
15 {
16     //int testMuilti = 0;   --- 这边初始值 你只要设定一个不在1~100的内都可以 它只是起判断作用
17     bool vis[110];
18     memset( vis , false , sizeof(vis) );
19     if( sum>n )
20         return;
21     else if( sum == n )
22     {
23         flag = true;
24         printf( "%d",temp[0] );
25         for( int i = 1 ; i<cnt ; i++ )
26         {
27             printf( "+%d",temp[i] );
28         }
29         printf( "\n" );
30     }
31     else
32     {
33         for( int i = pos ; i<m ; i++ )
34         {
35             if( sum+arr[i]<=n && !vis[ arr[i] ] )
36             {
37                 vis[ arr[i] ] = true;
38                 temp[cnt] = arr[i];
39                 dfs( sum+arr[i] , i+1 , cnt+1 );
40             }
41             /*
42             if( sum+arr[i]<=n && arr[i]!=testMuilti )
43             {
44                 testMuilti = arr[i];
45                 temp[cnt] = arr[i];
46                 dfs( sum+arr[i] , i+1 , cnt+1 );
47             }
48             */
49         }
50     }
51 }
52
53 int main()
54 {
55     while( ~scanf("%d %d",&n,&m)&&m )
56     {
57         flag = false;
58         for( int i = 0 ; i<m ; i++ )
59         {
60             scanf( "%d",&arr[i] );
61         }
62         printf( "Sums of %d:\n",n );
63         dfs(0,0,0);
64         if( !flag )
65             printf( "NONE\n" );
66     }
67     return 0;
68 }

搜索 还是很有意思的......

today:

  何日功成名遂了,还乡。醉笑陪公三万场

  酒不醉人人自醉  酒暖人心

TOJ--1343--dfs

时间: 2024-08-09 23:56:23

TOJ--1343--dfs的相关文章

UVa 1343 旋转游戏(dfs+IDA*)

https://vjudge.net/problem/UVA-1343 题意:如图所示,一共有8个1,8个2和8个3,如何以最少的移动来使得中间8个格子都为同一个数. 思路:状态空间搜索问题. 用IDA*算法的话会比较快,而且代码比较简洁. IDA*的关键就是要寻找一个估价函数h(),在这道题目中,每次移动最多只会使一个格子的数字正确,所以当maxd-d<h()时便可以剪枝. 1 #include<iostream> 2 #include<string> 3 #include

TOJ 1162 Fire Net(dfs)

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. A blockhouse is a small castle that has four openings through which to shoot. The fo

TOJ 1344 速算24点(全排列+dfs)

描述 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13).要求只用'+','-','*','/'运算符以及括号改变运算顺序,使得最终运算结果为24(每个数必须且仅能用一次).游戏很简单,但遇到无解的情况往往让人很郁闷.你的任务就是针对每一组随机产生的四张牌,判断是否有解.我们另外规定,整个计算过程中都不能出现小数. 输入 每组输入数据占一行,给定四张牌. 输出 每一组输入数据对应一行输出.如果有解则输出"Ye

TOJ 2850 Corn Fields 状压dp

Source: http://acm.tju.edu.cn/toj/showp.php?pid=2850 题意:n*m的土地上种东西,每个位置分为可以种和不能,种的方案要求不能相邻地种,问合法方案数.(写得有点乱) 分析:做过炮兵阵地,这题就是秒杀了. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int mo = 1000000

hihocoder 1343 : Stable Members【拓扑排序】

hihocoder #1343:题目 解释:一个学习小组,一共有N个学员,一个主管.每个学员都有自己的导师(一个或者多个),导师可以是其他学员也可以是主管.每周学员都要把自己的学习报告和收到的报告提交给自己的导师,这个团队设计很合理,没有回环(投递出去的报告不会回到自己手中),并且所有的报告最终都会投递到主管那里.但这个团队中有的学员会因为其他某个学员不工作而导致报告无法提交到主管手中,我们称这种学员为不可靠的.而不受某个学员不工作而影响到报告提交的就是可靠学员.问题就是找出可靠学员的数量. 输

TOJ刷题记录(2/50)

P1172:二分,最大化最小值 1 #include <algorithm> 2 #include <bitset> 3 #include <cctype> 4 #include <complex> 5 #include <cstdio> 6 #include <cstring> 7 #include <iostream> 8 #include <map> 9 #include <queue> 10

TOJ 1702.A Knight&#39;s Journey

2015-06-05 问题简述: 有一个 p*q 的棋盘,一个骑士(就是中国象棋里的马)想要走完所有的格子,棋盘横向是 A...Z(其中A开始 p 个),纵向是 1...q. 原题链接:http://acm.tju.edu.cn/toj/showp1702.html 解题思路: DFS:深搜把所有情况都考虑一遍,当骑士走出棋盘或走到原来走过的格子时,旅行失败了:当骑士能一直走下去直到走过的格子数等于 p*q 时,旅行成功. 提交过程中一直有一个问题使这个代码一直WA,最后才发现是 p.q输入反了

解救小哈——DFS算法举例

一.问题引入 有一天,小哈一个人去玩迷宫.但是方向感不好的小哈很快就迷路了.小哼得知后便去解救无助的小哈.此时的小哼已经弄清楚了迷宫的地图,现在小哼要以最快的速度去解救小哈.那么,问题来了... 二.问题的分析 首先我们用一个二维数组来存储这个迷宫,刚开始的时候,小哼处于迷宫的入口处(1,1),小哈在(p,q).其实这道题的的本质就在于找从(1,1)到(p,q)的最短路径. 此时摆在小哼面前的路有两条,我们可以先让小哼往右边走,直到走不通的时候再回到这里,再去尝试另外一个方向. 在这里我们规定一

【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)

[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依次更新这log位,如果最高位依然有进位,那么找到最高位后面的第一个0,将中间的所有1变成0,那个0变成1.这个显然要用到线段树,但是复杂度是nlog2n的,肯定过不去. 于是我在考场上yy了一下,这log位是连续的,我们每次都要花费log的时间去修改一个岂不是很浪费?我们可以先在线段树上找到这段区间