前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【第14题】题解及代码分享:这题不水吧,大模拟+全排列,[CCC 2008 S4] Twenty-four

【第14题】题解及代码分享:这题不水吧,大模拟+全排列,[CCC 2008 S4] Twenty-four

作者头像
小码匠
发布2023-11-27 15:25:12
2470
发布2023-11-27 15:25:12
举报

大家好,我是小码匠,今天继续划水,这道题真的不水,一开始没有考虑括号,样例过了,一提交就挂了。

后来看了看题解,学习了新思路。

前置知识

  • 全排列

路漫漫其修远兮,吾将上下而求索

离自己的既定目标:

  • 目标:300道
  • 已完成: 14道
  • 待完成:286道

题目描述

题目地址:

  • 洛谷:https://www.luogu.com.cn/problem/P9861

有一个算 24 点的游戏,每局游戏都会给你 4 个整数(1≤ 每个数 ≤13,表示你所需要用其来凑出 24 点。你可以将其中的两个数通过加减乘除的运算,得到一个新数,一直重复如此的操作,直到你剩下一个整数,那便是你游戏的答案。

现在,你需要根据给出的那 4 个整数,来计算出一个整数 n,使其最接近 24,同时也不能超出 24,问 n 是多少。

你一共玩了 N(1≤N≤5) 局这样的游戏,请你求出每局游戏对应的 n。

输入输出样例

输入 #1复制

代码语言:javascript
复制
3
3
3
3
3
1
1
1
1
12
5
13
1

输出 #1复制

代码语言:javascript
复制
24
4
21

题解

  • https://www.luogu.com.cn/problem/solution/P9861
AC代码
代码语言:javascript
复制
#include <bits/stdc++.h>

using namespace std;

int n, a[4];
bool is;

int answer(int x, int y, int t) {
    if (t == 0) {
        return x + y;
    }
    if (t == 1) {
        return x - y;
    }
    if (t == 2) {
        return x * y;
    }
    if (t == 3 && y != 0 && x % y == 0) {
        return x / y;
    }
    is = false;
    return 0;
}

void best_coder() {
    cin >> n;
    while (n--) {
        int ans = 0;
        for (int i = 0; i < 4; ++i) {
            cin >> a[i];
        }
        do {
            for (int i = 0; i < 4; ++i) {
                for (int j = 0; j < 4; ++j) {
                    for (int s = 0; s < 4; ++s) {
                        is = true;
                        int cnt = answer(answer(answer(a[0], a[1], i), a[2], j), a[3], s);
                        if (is && cnt <= 24) {
                            ans = max(ans, cnt);
                        }
                        is = true;
                        cnt = answer(answer(a[0], answer(a[1], a[2], j), i), a[3], s);
                        if (is && cnt <= 24) {
                            ans = max(ans, cnt);
                        }
                        is = true;
                        cnt = answer(a[0], answer(a[1], answer(a[2], a[3], s), j), i);
                        if (is && cnt <= 24) {
                            ans = max(ans, cnt);
                        }
                        is = true;
                        cnt = answer(answer(a[0], a[1], i), answer(a[2], a[3], s), j);
                        if (is && cnt <= 24) {
                            ans = max(ans, cnt);
                        }
                        is = true;
                        cnt = answer(a[0], answer(answer(a[1], a[2], j), a[3], s), i);
                        if (is && cnt <= 24) {
                            ans = max(ans, cnt);
                        }
                    }
                }
            }
        } while (next_permutation(a, a + 4));
        cout << ans << '\n';
    }
}

void happy_coder() {

}

int main() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    return 0;
}
学习代码
代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;

int ans;
int hand[4];                   // The given card hand.
vector<int> hand_permutation;  // The generated permutation of the card hand.
bool chosen[4];  // Whether a given card is present in `hand_permutation`.

// Function that takes in two numbers and an operation and returns the result.
int operation(int op, int num1, int num2) {
	switch (op) {
	case 0:
		return num1 + num2;
	case 1:
		return num1 - num2;
	case 2:
		return num1 * num2;
	case 3: {
		// The divisor cannot be 0 and the quotient must be a whole number.
		if (num2 == 0 || num1 % num2 != 0) { return INT32_MIN; }
		return num1 / num2;
	}
	}
	return INT32_MIN;
}

// Function that generates all possible permutations of the card hand.
void generate_hand_permutation() {
	if (hand_permutation.size() == 4) {
		// We have generated a permutation, so we can try placing the
		// operators.
		for (int op1 = 0; op1 < 4; op1++) {
			for (int op2 = 0; op2 < 4; op2++) {
				for (int op3 = 0; op3 < 4; op3++) {
					int first = operation(op1, hand_permutation[0],
					                      hand_permutation[1]);
					// If the operation is invalid, continue;
					if (first == INT32_MIN) { continue; }

					int second = operation(op2, first, hand_permutation[2]);
					if (second == INT32_MIN) { continue; }

					int third = operation(op3, second, hand_permutation[3]);
					if (third == INT32_MIN) { continue; }

					if (third <= 24) { ans = max(ans, third); }
				}
			}
		}

		// Case 2: (( ) ( ))
		for (int op1 = 0; op1 < 4; op1++) {
			for (int op2 = 0; op2 < 4; op2++) {
				for (int op3 = 0; op3 < 4; op3++) {
					int first = operation(op1, hand_permutation[0],
					                      hand_permutation[1]);
					if (first == INT32_MIN) { continue; }

					int second = operation(op2, hand_permutation[2],
					                       hand_permutation[3]);
					if (second == INT32_MIN) { continue; }

					int third = operation(op3, first, second);
					if (third == INT32_MIN) { continue; }

					if (third <= 24) { ans = max(ans, third); }
				}
			}
		}
	} else {
		// Otherwise, we continue to build our permutation array.
		for (int i = 0; i < 4; i++) {
			if (chosen[i]) continue;
			chosen[i] = true;
			hand_permutation.push_back(hand[i]);
			generate_hand_permutation();
			chosen[i] = false;
			hand_permutation.pop_back();
		}
	}
}

int main() {
	int num_hands;
	cin >> num_hands;

	for (int h = 0; h < num_hands; h++) {
		ans = INT32_MIN;
		for (int i = 0; i < 4; i++) { cin >> hand[i]; }

		// Start complete search.
		generate_hand_permutation();
		cout << ans << "\n";
	}
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-11-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小码匠和老码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前置知识
  • 路漫漫其修远兮,吾将上下而求索
  • 题目描述
    • 输入输出样例
    • 题解
      • AC代码
        • 学习代码
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档