第三章 枚举、暴力

#

奥数

将数字1~9填入等式“??? + ??? = ???”使等式成立
//没耐心等他跑完
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(void)
{
    int count = 0;
    vector<int> nums(9);  //等式数字
    vector<bool> flags(9);  //1~9使用标记

    for(nums[0] = 1; nums[0] <= 9; ++nums[0])
        for(nums[1] = 1; nums[1] <= 9; ++nums[1])
            for(nums[2] = 1; nums[2] <= 9; ++nums[2])
                for(nums[3] = 1; nums[3] <= 9; ++nums[3])
                    for(nums[4] = 1; nums[4] <= 9; ++nums[4])
                        for(nums[5] = 1; nums[5] <= 9; ++nums[5])
                            for(nums[6] = 1; nums[6] <= 9; ++nums[6])
                                for(nums[7] = 1; nums[7] <= 9; ++nums[7])
                                    for (nums[8] = 1; nums[8] <= 9; ++nums[8])
                                    {
                                        fill(flags.begin(), flags.end(), false);  //初始化标记数组
                                        for (int i = 0; i < 9; ++i)
                                            flags[nums[i] - 1] = true;
                                        if (find(flags.begin(), flags.end(), false) != flags.end())
                                            continue;
                                        cout << nums[0] << nums[1] << nums[2] << '+'
                                            << nums[3] << nums[4] << nums[5] << '='
                                            << nums[6] << nums[7] << nums[8] << endl;
                                        int a = nums[0] * 100 + nums[1] * 10 + nums[2];
                                        int b = nums[3] * 100 + nums[4] * 10 + nums[5];
                                        int c = nums[6] * 100 + nums[7] * 10 + nums[8];
                                        if (a + b == c)
                                        {
                                            ++count;
                                            cout << nums[0] << nums[1] << nums[2] << '+'
                                                << nums[3] << nums[4] << nums[5] << '='
                                                << nums[6] << nums[7] << nums[8] << endl;
                                        }
                                    }
    cout << "\ntotal=" << count / 2 << endl;

    return 0;
}
快一点的
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(void)
{
    int count = 0;
    vector<bool> flags(10);  //0~9使用标记

    for(int i = 123; i <= 987; ++i)
        for(int j = 123; j <= 987; ++j)
            for (int k = 123; k <= 987; ++k)
            {
                if (i + j != k)  //大概率剪枝
                    continue;
                fill(flags.begin(), flags.end(), false);
                flags[i / 100] = true;
                flags[(i / 10) % 10] = true;
                flags[i % 10] = true;
                flags[j / 100] = true;
                flags[(j / 10) % 10] = true;
                flags[j % 10] = true;
                flags[k / 100] = true;
                flags[(k / 10) % 10] = true;
                flags[k % 10] = true;
                if (find(flags.begin() + 1, flags.end(), false) != flags.end())  //排除0
                    continue;
                ++count;
                cout << i << '+' << j << '=' << k << endl;
            }
    cout << "\ntotal=" << count / 2 << endl;

    return 0;
}

炸弹人

计算炸弹放在那里才能消灭最多敌人
墙用#表示,空地用.表示,敌人用G表示
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.###
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
枚举法,但是没考虑是否能走到对应坐标点放置炸弹
#include<iostream>
#include<vector>
#include<string>

using namespace std;

int main(void)
{
    vector<string> map = {
        "#############",
        "#GG.GGG#GGG.#",
        "###.#G#G#G#G#",
        "#.......#..G#",
        "#G#.###.#G#G#",
        "#GG.GGG.#.GG#",
        "#G#.#G#.#.###",
        "##G...G.....#",
        "#G#.#G###.#G#",
        "#...G#GGG.GG#",
        "#G#.#G#G#.#G#",
        "#GG.GGG#G.GG#",
        "#############"
    };

    //统计最多的敌人数和坐标
    int max_count = 0;
    int max_x;
    int max_y;

    //两重循环枚举每一点
    for (int i = 0; i < map.size(); ++i)
    {
        for (int j = 0; j < map[0].size(); ++j)
        {
            if (map[i][j] == '.')  //是平地才可以放置炸弹
            {
                int sum = 0;
                int x = i;
                int y = j;
                while (map[x][y] != '#')  //向下
                {
                    if (map[x][y] == 'G')  //是敌人
                        ++sum;
                    ++x;
                }
                x = i;
                y = j;
                while (map[x][y] != '#')  //向上
                {
                    if (map[x][y] == 'G')
                        ++sum;
                    --x;
                }
                x = i;
                y = j;
                while (map[x][y] != '#')  //向右
                {
                    if (map[x][y] == 'G')
                        ++sum;
                    ++y;
                }
                x = i;
                y = j;
                while (map[x][y] != '#')  //向左
                {
                    if (map[x][y] == 'G')
                        ++sum;
                    --y;
                }
                if (sum > max_count)
                {
                    max_count = sum;
                    max_x = i;
                    max_y = j;
                }
            }
        }
    }

    cout << '(' << max_x << ',' << max_y << ")==>" << max_count << endl;

    return 0;
}

火柴棍等式

假设有m根火柴(m≤24),可以拼出多少个形如A+B=C的等式?
除去+和=占用的四根火柴,最多剩下20根火彩。而在0-9这10个数字中,数字1需要用到的火柴棍最少,只需两根火柴棍。而20根火柴棍最多能组成10个1。因此A+B=C中A、B、C任意一个数都不能超过11111。
枚举A、B、C的时间复杂度为O(N^3)≈11112^3,通过A和B计算出C,枚举少一个数,将复杂度变为O(N^2)
#include<iostream>

using namespace std;

int count(int x)  //计算数字对应的火柴棍数目
{
    const static int NUMS[] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 };
    int num = 0;
    while (x)
    {
        num += NUMS[x % 10];
        x /= 10;
    }
    if (num == 0)  //零的情况
        num += NUMS[0];
    return num;
}

int main(void)
{
    int all = 24;  //24根火柴
    int sum = 0;  //统计等式个数
    for (int a = 0; a <= 11111; ++a)
    {
        for (int b = 0; b <= 11111; ++b)
        {
            int c = a + b;
            if (count(a) + count(b) + count(c) + 4 == all)
            {
                cout << a << '+' << b << '=' << c << endl;
                ++sum;
            }
        }
    }
    cout << sum << endl;
    return 0;
}

数的全排列

123的全排列需要用三个循环枚举每一位,不相等时输出
#include<iostream>

using namespace std;

int main(void)
{
    for (int a = 1; a <= 3; ++a)
        for (int b = 1; b <= 3; ++b)
            for (int c = 1; c <= 3; ++c)
            {
                if (a != b && b != c && a != c)
                    cout << a << b << c << endl;
            }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值