贪心算法

 

1.      深度优先搜索DFS:

1:给定整数a0,a1….an,判断是否可以从中选出若干数,使它们的和恰好为K。

#include<stdio.h>
bool  DFS ( int i, int sum )  //已从ai之前所有项中得到和sum,现对a[i]进行判断。
{ if  ( i==n ) return sum==k;
if  ( DFS ( i+1, sum ) )  return  true;
if  ( DFS ( i+1, sum+a[i] ) )  return  true;
return  false ; }
void  main ( ) {
if  ( DFS ( 0, 0 ) )  printf ( "yes\n" );
else  printf ( " no\n " ) ; 
}

例2.剪格子游戏

在3*3的格子中填一些数,使得左上角的数之和等于除左上角外的所有数之和。

存在多种答疑方法时请选择左上角格子数最小的情况

 1 #include <stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 int map[20][20], vis[20][20], s, n, m;
 7 int to[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };
 8 int dfs(int x, int y, int sum)
 9 {
10     if (sum == s)
11         return 1;
12     int ans = 0;
13     for (int i = 0; i < 4; i++)
14     {
15         int tx = x + to[i][0];
16         int ty = y + to[i][1];
17         if (tx >= 0 && tx < n&&ty >= 0 && ty < m)
18         {
19             if (!vis[tx][ty] && map[tx][ty] + sum <= s)
20             {
21                 vis[tx][ty] = 1;
22                 ans = dfs(tx, ty, map[tx][ty] + sum);
23                 if (ans)
24                     return ans + 1;
25                 vis[tx][ty] = 0;
26             }
27         }
28     }
29     return 0;
30 }
31 int main()
32 {
33     int i, j;
34     int sum = 0;
35     cin >> m >> n;
36     for (i = 0; i < n; i++)
37     {
38         for ( j = 0; j < m; j++)
39         {
40             cin >> map[i][j];
41             sum += map[i][j];
42         }
43 
44     }
45     if (sum % 2)
46         printf("0\n");
47     else if (map[0][0] == sum / 2)
48         printf("1\n");
49     else
50     {
51         s = sum / 2;
52         memset(vis, 0, sizeof(vis));
53         vis[0][0] = 1;
54         printf("%d\n", dfs(0, 0, map[0][0]));
55     }
56     return 0;
57 }
剪格子算法

2.深度优先搜索BFS:

在一个二维的格子迷宫计算最短路径

学霸的迷宫:

第一行n,m为迷宫的长宽。接下来n行,每行m个数,数之间没有间隔,为0或1的一个,0表示可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫出口在(m,n)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)课通过。

 1 #include <iostream>  
 2 #include <string.h>  
 3 #include <cstdio>  
 4 #include <queue>  
 5 #include <algorithm>  
 6 using namespace std;
 7 const int N = 500 + 10;
 8 char map[N][N];
 9 int n, m;
10 bool book[N][N];
11 struct Node{
12     int x, y, t;
13     string s;
14 }node, tmp;
15 char c[6] = "DLRU";
16 int step[4][2] = { { 1, 0 }, { 0, -1 }, { 0, 1 }, { -1, 0 } };   //字典序顺序 下左右上   {U,D,L,R}   
17 queue<Node> q;
18 int main()
19 {
20     int i, j;
21     while (cin >> n >> m){
22         for (i = 1; i <= n; i++)
23         for (j = 1; j <= m; j++){
24             cin >> map[i][j];
25             book[i][j] = 0;
26         }
27 
28         node.x = 1;
29         node.y = 1;
30         node.t = 0;
31         node.s = "";
32         q.push(node);
33         while (!q.empty()){
34             tmp = q.front();
35             if (tmp.x == n&&tmp.y == m)
36                 break;
37             q.pop();
38             for (i = 0; i<4; i++){
39                 int a = tmp.x + step[i][0];
40                 int b = tmp.y + step[i][1];
41                 if (a<1 || a>n || b<1 || b>m || book[a][b] || map[a][b] == '1')
42                     continue;
43                 book[a][b] = 1;
44                 node.x = a;
45                 node.y = b;
46                 node.t = tmp.t + 1;
47                 node.s = tmp.s + c[i];
48                 q.push(node);
49             }
50         }
51         cout << tmp.t << endl;
52         cout << tmp.s << endl;
53     }
54     return 0;
55 }

3.剪枝

若已知从当前状态无论如何转移都不会存在解,则直接跳过,不再继续搜索,称为剪枝。

如:在例1的搜索过程中,只要sum超过K,则不再继续搜索。

100

4  带分数(蓝桥杯:历届试题)

100可以表示为带分数的形势:100=3+69258/714

还可以表示为:100=82+3546/197

带分数中数字1~9分别出现且只出现一次(不包含0)。

累死这样的分数100中有11中表示法

现将这些用代码表示出来

 1      #include <stdio.h>
 2      #include <string.h>
 3      #include <algorithm>
 4      int visit[10];
 5      int a[10];
 6      int kind = 0;
 7      int sum(int begin, int end)
 8      {int s = 0;
 9      for (int i = begin; i <= end; i++)
10      s = s * 10 + a[i];
11      return s;
12      }
13      void check(int a[], int value)
14      {int num = 0, temp = value;
15          for (int temp = value; temp != 0; temp = temp / 10) num++;
16          for (int k = 1; k <= num; k++)
17            {int left = sum(1, k);
18             if (left >= value) return;
19             for (int j = 5 + k / 2; j<9; j++)
20                    {int top = sum(k + 1, j);
21                 int down = sum(j + 1, 9);
22                 if (top>down&&top%down == 0 && value == left + top / down)
23                    kind++;
24                 }
25              }
26      }
27      void dfs(int start, int value)
28      { if (start>9)
29        {check(a, value); }
30     else{
31             for (int i = 1; i <= 9; i++)
32                   { if (!visit[i])
33             {a[start] = i;
34             visit[i] = 1;
35             dfs(start + 1, value);
36                 visit[i] = 0; }
37           }
38     
39 }
40     }
41     int main()
42     {int value;
43     memset(visit, 0, sizeof(visit));
44     memset(a, 0, sizeof(a));
45     scanf("%d", &value);
46     dfs(1, value);
47     printf("%d\n", kind);
48     return 0;
49     }
带分数

 

 

 

 

posted @ 2019-03-04 21:10  insist钢  阅读(319)  评论(0编辑  收藏  举报