返回目录
题目描述
有N条线段,长度分别为a[1]-a[n]。
现要求你计算这N条线段最多可以组合成几个直角三角形。
每条线段只能使用一次,每个三角形包含三条线段。
输入描述
第一行输入一个正整数T(1<=T<=100),表示有T组测试数据.
对于每组测试数据,接下来有T行,
每行第一个正整数N,表示线段个数(3<=N<=20),接着是N个正整数,表示每条线段长度,(0<a[i]<100)。
输出描述
对于每组测试数据输出一行,每行包括一个整数,表示最多能组合的直角三角形个数
示例:
输入 | 1 7 3 4 5 6 5 12 13 |
---|---|
输出 | 2 |
说明 | 可以组成2个直角三角形(3,4,5)、(5,12,13) |
Python算法源码
from itertools import combinations
#用于存储每个状态的信息
class TriangleState:
def __init__(self, index, count, used):
self.index = index
self.count = count
self.used = used
#用于执行非递归深度优先搜索
def iterative_dfs(lengths):
max_triangles = 0
used_segments = [False] * len(lengths)
stack = [TriangleState(0, 0, used_segments)]
# 遍历状态栈
while stack:
current_state = stack.pop()
current_index = current_state.index
current_count = current_state.count
used_segments = current_state.used
max_triangles = max(max_triangles, current_count)
# 遍历线段数组,从current_index开始
x = current_index
while x < len(lengths) - 2:
y = x + 1
while y < len(lengths) - 1:
z = y + 1
while z < len(lengths):
if used_segments[x] or used_segments[y] or used_segments[z]:
z += 1
continue
# 检查当前三条线段是否满足勾股定理
if lengths[x] ** 2 + lengths[y] ** 2 == lengths[z] ** 2:
new_used_segments = used_segments.copy()
new_used_segments[x] = True
new_used_segments[y] = True
new_used_segments[z] = True
stack.append(TriangleState(x + 1, current_count + 1, new_used_segments))
z += 1
y += 1
x += 1
return max_triangles
# 用于读取测试数据组数并返回
def read_test_cases():
return int(input())
# 用于读取每组测试数据并返回
def read_input_data(test_cases):
input_data = []
for _ in range(test_cases):
input_data.append(list(map(int, input().split()))[1:])
return input_data
# 用于处理每组测试数据并输出结果
def process_test_cases(input_data):
for testCase in input_data:
# 对线段长度进行升序排序
testCase.sort()
# 调用iterative_dfs函数并输出结果
print(iterative_dfs(testCase))
# 读取测试数据组数
num_test_cases = read_test_cases()
# 读取每组测试数据
test_data = read_input_data(num_test_cases)
# 处理每组测试数据并输出结果
process_test_cases(test_data)
c算法源码
#include <stdio.h>
#include <stdbool.h>
// 结构体用于存储状态信息
typedef struct {
int index; // 当前索引
int count; // 已找到的直角三角形数量
bool *used; // 已使用的线段
} State;
// 非递归深度优先搜索函数
int non_recursive_dfs(int *lengths, int length_count) {
int max_triangles = 0;
bool *used_segments = malloc(length_count * sizeof(bool));
State *stack = malloc(length_count * sizeof(State));
int stack_top = -1;
// 初始化used_segments数组
for (int i = 0; i < length_count; i++)
used_segments[i] = false;
// 将初始状态压入栈中
stack[++stack_top] = (State){0, 0, used_segments};
// 遍历栈
while (stack_top >= 0) {
State current_state = stack[stack_top--];
int current_index = current_state.index;
int current_count = current_state.count;
used_segments = current_state.used;
max_triangles = (max_triangles > current_count) ? max_triangles : current_count;
// 遍历长度数组,从current_index开始
for (int i = current_index; i < length_count - 2; i++) {
for (int j = i + 1; j < length_count - 1; j++) {
for (int k = j + 1; k < length_count; k++) {
if (used_segments[i] || used_segments[j] || used_segments[k])
continue;
// 检查当前三条线段是否满足勾股定理
if (lengths[i] * lengths[i] + lengths[j] * lengths[j] == lengths[k] * lengths[k]) {
bool *new_used_segments = malloc(length_count * sizeof(bool));
for (int l = 0; l < length_count; l++)
new_used_segments[l] = used_segments[l];
new_used_segments[i] = true;
new_used_segments[j] = true;
new_used_segments[k] = true;
// 将新状态压入栈中
stack[++stack_top] = (State){i + 1, current_count + 1, new_used_segments};
}
}
}
}
free(current_state.used);
}
free(stack);
return max_triangles;
}
int main() {
int test_cases;
scanf("%d", &test_cases);
// 读取和处理每个测试用例
for (int i = 0; i < test_cases; i++) {
int length_count;
scanf("%d", &length_count);
int lengths[length_count];
// 读取当前测试用例的线段长度
for (int j = 0; j < length_count; j++)
scanf("%d", &lengths[j]);
// 将线段长度升序排序
for (int j = 0; j < length_count - 1; j++) {
for (int k = 0; k < length_count - j - 1; k++) {
if (lengths[k] > lengths[k + 1]) {
int temp = lengths[k];
lengths[k] = lengths[k + 1];
lengths[k + 1] = temp;
}
}
}
// 调用non_recursive_dfs函数并输出结果
printf("%d\n", non_recursive_dfs(lengths, length_count));
}
return 0;
}
java算法源码
import java.util.Scanner;
// 用于存储状态信息的类
class State {
int index; // 当前索引
int count; // 已找到的直角三角形数量
boolean[] used; // 已使用的线段
// 构造函数
State(int index, int count, boolean[] used) {
this.index = index;
this.count = count;
this.used = used.clone(); // 使用克隆避免浅拷贝问题
}
}
public class Main {
// 非递归深度优先搜索函数
static int nonRecursiveDFS(int[] lengths) {
int maxTriangles = 0;
int lengthCount = lengths.length;
boolean[] usedSegments = new boolean[lengthCount];
State[] stack = new State[lengthCount];
int stackTop = -1;
// 将初始状态压入栈中
stack[++stackTop] = new State(0, 0, usedSegments.clone());
// 遍历栈
while (stackTop >= 0) {
State currentState = stack[stackTop--];
int currentIndex = currentState.index;
int currentCount = currentState.count;
boolean[] currentUsedSegments = currentState.used;
maxTriangles = Math.max(maxTriangles, currentCount);
// 遍历长度数组,从currentIndex开始
for (int i = currentIndex; i < lengthCount - 2; i++) {
for (int j = i + 1; j < lengthCount - 1; j++) {
for (int k = j + 1; k < lengthCount; k++) {
if (currentUsedSegments[i] || currentUsedSegments[j] || currentUsedSegments[k])
continue;
// 检查当前三条线段是否满足勾股定理
if (lengths[i] * lengths[i] + lengths[j] * lengths[j] == lengths[k] * lengths[k]) {
boolean[] newUsedSegments = currentUsedSegments.clone();
newUsedSegments[i] = true;
newUsedSegments[j] = true;
newUsedSegments[k] = true;
// 将新状态压入栈中
stack[++stackTop] = new State(i + 1, currentCount + 1, newUsedSegments);
}
}
}
}
}
return maxTriangles;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int testCases = scanner.nextInt();
// 读取和处理每个测试用例
for (int t = 0; t < testCases; t++) {
int lengthCount = scanner.nextInt();
int[] lengths = new int[lengthCount];
// 读取当前测试用例的线段长度
for (int i = 0; i < lengthCount; i++)
lengths[i] = scanner.nextInt();
// 将线段长度升序排序
for (int i = 0; i < lengthCount - 1; i++) {
for (int j = 0; j < lengthCount - i - 1; j++) {
if (lengths[j] > lengths[j + 1]) {
int temp = lengths[j];
lengths[j] = lengths[j + 1];
lengths[j + 1] = temp;
}
}
}
// 调用nonRecursiveDFS函数并输出结果
System.out.println(nonRecursiveDFS(lengths));
}
}
}
2 条评论
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]