POJ1014 解题报告(DFS)

题目在此:http://poj.org/problem?id=1014

  要看清题意呢,题中要求输入的是价值分别为1,2,3,4,5,6的大理石的个数,而不是6块价值为输入数字的大理石!选这个题主要想练习一下深搜。在网上看到了一段代码,深搜时使用了贪心算法虽然可以AC但是有很大的漏洞:

  如测试数据(0 0 3 0 3 1)便会出现错误:

   搜索时候会选中:价值为6,5,3的各一个进而判断出不可以分割。但是正确的分割方式应该是6+3+3+3=15。

这个是网上有漏洞的代码:

 1 #include<iostream>
 2 using namespace std;
 3
 4 int amount[7] = {0};
 5 int half_value = 0;
 6 int flag = 0;
 7
 8 void DFS(int value, int pre){
 9
10     if(value == half_value){
11         flag = 1;
12         return;
13     }
14
15     if(flag == 1){  //这个可以去掉的啊!
16         return;
17     }
18
19     int i = 0;
20     for(i = pre; i > 0; i--){
21         if(amount[i]){
22             if(i + value <= half_value){
23                 amount[i]--;
24                 DFS(i + value, i);
25
26                 if(flag == 1){  //不可少的,感受其作用,让递归栈中所有DFS结束
27                     return;
28                 }
29             }
30         }
31     }
32 }
33
34
35 int main(){
36
37     int testcase = 1;
38     while(true){
39         flag = 0;
40         int totalvalue = 0;
41         int N = 6;
42         int i = 1;
43         while(i <= N){
44             cin >> amount[i];
45             totalvalue += amount[i] * i;
46             i++;
47         }
48
49         if(!amount[1] && !amount[2] && !amount[3] && !amount[4] && !amount[5] && !amount[6]){
50             break;
51         }
52
53         printf("Collection #%d:\n", testcase++);
54         if(totalvalue % 2 != 0){
55             cout << "Can‘t be divided." << endl << endl;
56             continue;
57         }
58
59         half_value = totalvalue / 2;
60         DFS(0, 6);
61
62         if(flag){
63             cout << "Can be divided." << endl;
64         } else {
65             cout << "Can‘t be divided." << endl;
66         }
67         cout << endl;
68     }
69     return 0;
70 }  

有漏洞的代码

  为了解决这个问题,在判定不能分割之前又加入了一个循环,即从价值为5,4...1的大理石开始深搜,这样就避免了以上代码的漏洞。因为贪心算法基本解决了大部分的情况,故这个循环不会引起超时。以下是修改过的代码:

#include<iostream>
#include <string.h>
#include<stdio.h>
using namespace std;

int amount[7] = { 0 };
int temp_amount[7] = { 0 };//存下原始输入值
int half_value = 0;
int flag = 0;

void DFS(int value, int pre)
{
    if (value == half_value)
    {
        flag = 1;
        return;
    }

    int i = 0;
    for (i = pre; i > 0; i--)
    {
        if (amount[i]) {
            if (i + value <= half_value)
            {
                amount[i]--;
                DFS(i + value, i);

                if (flag == 1)
                {
                    return;
                }
            }
        }
    }

}
int main() {

    int testcase = 1;
    while (true)
    {
        flag = 0;
        int totalvalue = 0;
        int N = 6;
        int i = 1;
        while (i <= N)
        {
            cin >> temp_amount[i];
            totalvalue += temp_amount[i] * i;
            i++;
        }

        if (!temp_amount[1] && !temp_amount[2] && !temp_amount[3] && !temp_amount[4] && !temp_amount[5] && !temp_amount[6])
        {
            break;
        }
        printf("Collection #%d:\n", testcase++);
        if (totalvalue % 2 != 0)
        {
            cout << "Can‘t be divided." << endl << endl;
            continue;
        }
        half_value = totalvalue / 2;

        memcpy(amount, temp_amount, 7 * sizeof(int));
        DFS(0, 6);

        if (flag)
            cout << "Can be divided." << endl;

        else
        {
            for (int m = 6; m >= 1; m--)
            {
                if (!flag)
                {
                    memcpy(amount, temp_amount, 7 * sizeof(int));//因为amount数组已经被操作,故需要恢复
                    DFS(0, m);
                }
            }
            if (!flag)
                cout << "Can‘t be divided." << endl;
            else
                cout << "Can be divided." << endl;
        }
        cout << endl;
    }
    return 0;
}

(以后再进行补充呃)

  

时间: 2024-10-11 00:07:03

POJ1014 解题报告(DFS)的相关文章

【解题报告】Tempter of the Bone(DFS)

解题报告——Tempter of the Bon 问题描述 Time Limit: 1000ms Memory Limit: 32768KB 64-bit integer IO format: %I64d      Java class name: Main The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to

poj分类解题报告索引

图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Journey poj1724 - ROADS(邻接表+DFS) BFS poj3278 - Catch That Cow(空间BFS) poj2251 - Dungeon Master(空间BFS) poj3414 - Pots poj1915 - Knight Moves poj3126 - Prim

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

解题报告 之 UVA563 Crimewave

解题报告 之 UVA563 Crimewave Description Nieuw Knollendam is a very modern town. This becomes clear already when looking at the layout of its map, which is just a rectangular grid of streets and avenues. Being an important trade centre, Nieuw Knollendam a

CH Round #56 - 国庆节欢乐赛解题报告

最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树,其中一些树上结有能够产生能量的魔力水果.已知每个水果的位置(Xi,Yi)以及它能提供的能量Ci.然而,魔幻森林在某些时候会发生变化:(1) 有两行树交换了位置.(2) 有两列树交换了位置.当然,树上结有的水果也跟随着树一起移动.不过,只有当两行(列)包含的魔力水果数都大于0,或者两行(列)都没有魔

poj 3020 Antenna Placement 解题报告

题目链接:http://poj.org/problem?id=3020 题目意思:首先,请忽略那幅有可能误导他人成分的截图(可能我悟性差,反正有一点点误导我了). 给出一幅 h * w 的图,  “ * ” 表示 point of interest,“ o ” 忽略之.你可以对 " * " (假设这个 “* ”的坐标是 (i, j))画圈,每个圈只能把它四周的某一个点括住(或者是上面(i-1, j) or 下面(i+1, j) or 左边(i, j-1)  or 右边(i, j+1))

poj 1469 COURSES 解题报告

题目链接:http://poj.org/problem?id=1469 题目意思:略 for 循环中遍历的对象要特别注意,究竟是遍历课程数P 还是 学生数N,不要搞混! 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 300 + 5; 7 int match[maxn], map[maxn][maxn];

解题报告【pat-1076】

最近一直在忙项目都没时间好好总结写博客,说起来真实惭愧啊. 下面就把自己最近做的几题好好总结一下,主要记录一些注意点,以防以后遇到再犯. 1076. Forwards on Weibo (30) 时间限制 3000 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Weibo is known as the Chinese version of Twitter.  One user on Weibo may have many

Codeforces Round #259 (Div. 2) 解题报告

终于重上DIV1了.... A:在正方形中输出一个菱形 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月01日 星期五 23时27分55秒 4 5 #include<vector> 6 #include<set> 7 #include<deque> 8 #include<stack> 9 #include<bitset> 10 #inclu