火柴拼正方形(回溯算法)
2023-12-13 06:05:14
将得到一个整数数组matchsticks ,其中matchsticks[i]是第 i 个火柴棒的长度。要用所有的火柴棍拼成一个正方形,并且不能折断任何一根火柴棒,但可以把它们连在一起,而且每根火柴棒必须使用一次。如果能拼成这个正方形,则返回true ,否则返回false。
示例 1:
输入: (存放火柴棒长度的列表matchsticks)
[1,1,2,2,2]
输出:?
True
解释: 能拼成一个边长为2的正方形,每边两根火柴。
示例 2:
输入: (存放火柴棒长度的列表matchsticks)
[3,3,3,3,4]
输出:?
False
解释: 不能用所有火柴拼成一个正方形。
def makeSquare(matchsticks):
totalLen = sum(matchsticks)
if totalLen % 4 != 0:
return False
matchsticks.sort(reverse=True)
edges = [0 for i in range(4)]
def dfs(idx):
if idx == len(matchsticks):
return True
for i in range(4):
edges[i] += matchsticks[idx]
if edges[i] <= totalLen // 4 and dfs(idx + 1):
return True
edges[i] -= matchsticks[idx]
return False
return dfs(0)
matchsticks = eval(input())
print(makeSquare(matchsticks))
#include <vector>
#include <algorithm>
bool makesquare(std::vector<int>& matchsticks) {
int sum = 0;
for (int stick : matchsticks) {
sum += stick;
}
if (sum % 4 != 0) {
return false; // 总长度不能被4整除,无法构成正方形
}
int targetSideLength = sum / 4;
std::sort(matchsticks.begin(), matchsticks.end()); // 将火柴棒按长度从小到大排序
return backtrack(matchsticks, targetSideLength, 0, 0, 0);
}
bool backtrack(std::vector<int>& matchsticks, int targetSideLength, int index, int currentSideLength, int currentSticksUsed) {
if (index == matchsticks.size()) {
return currentSideLength == targetSideLength; // 所有火柴棒都已使用,检查是否形成了正方形
}
for (int i = 0; i < 4; i++) {
if (currentSideLength + matchsticks[index] > targetSideLength) {
break; // 当前边长加上当前火柴棒的长度超过了目标边长,尝试下一个位置
}
if (currentSticksUsed + 1 > matchsticks.size()) {
return false; // 已经使用了超过所有火柴棒的次数,无法形成正方形
}
if (backtrack(matchsticks, targetSideLength, index + 1, currentSideLength + matchsticks[index], currentSticksUsed + 1)) {
return true; // 在当前位置成功形成了正方形,返回true
}
}
return false; // 在所有位置都无法形成正方形,返回false
}
?
public boolean makesquare(int[] matchsticks) {
int n = matchsticks.length;
int sum = 0;
for (int matchstick : matchsticks) {
sum += matchstick;
}
int target = (int) Math.sqrt(sum);
if (target * target != sum) {
return false;
}
int[][] dp = new int[n + 1][target + 1];
for (int i = 0; i <= n; i++) {
Arrays.fill(dp[i], -1);
}
return dfs(matchsticks, 0, target, dp);
}
private boolean dfs(int[] matchsticks, int index, int target, int[][] dp) {
if (index == matchsticks.length) {
return target == 0;
}
if (dp[index][target] != -1) {
return dp[index][target] == 1;
}
for (int j = 1; j <= target; j++) {
if (matchsticks[index] <= j && dfs(matchsticks, index + 1, target - j, dp)) {
dp[index][target] = 1;
return true;
}
}
dp[index][target] = 0;
return false;
}
文章来源:https://blog.csdn.net/m0_73811154/article/details/134962087
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!