Dream__Sky @ 2022-07-04 16:29:12
4.三角形(triangle)
题目描述
小魏有 3*n 根颜色两两不同的木棍,第i根的长度为a[i]。
小魏想把这3*n根木棍分成n组,每组三根,并且同一组的三根木棍可以组成一个三角形。
小魏想知道他有多少种不同的分组方案。认为两个分组方案是不同的,当且仅当两种方案组出来的三角形是不同的。
输入
第一行一个整数n。
第二行n个整数a[i]。
输出
一行一个整数,表示方案数。
样例输入输出
输入
2
3 4 5 10 11 12
输出
1
提示
对于20% 的数据,n=1;
对于50% 的数据,n≤3;
对于70% 的数据,n≤4;
另有10% 的数据,所有a[i] 全部相等;
对于所有数据,1≤n≤5, 1≤a[i] ≤100。
by thomaswmy @ 2022-08-16 14:10:58
@金宇昂 我做过这题
把我的代码放这吧
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n,a[100];
int nxt[100],pre[100];
int head=1;
ll ans;
int an[100];
void dfs(int dep,int sum,int lst) {
if(dep>n*3) {
ans++;
return ;
}
if(dep%3==0) {
for(int i=lst;a[i]<sum && i<=n*3;i=nxt[i]) {
nxt[pre[i]]=nxt[i];
pre[nxt[i]]=pre[i];
an[dep]=i;
if(i==head) {
head=nxt[i];
dfs(dep+1,0,head);
nxt[pre[i]]=i;
pre[nxt[i]]=i;
head=i;
}
else {
dfs(dep+1,0,head);
nxt[pre[i]]=i;
pre[nxt[i]]=i;
}
}
}
else if(dep%3==2){
for(int i=lst;i<=n*3;i=nxt[i]) {
nxt[pre[i]]=nxt[i];
pre[nxt[i]]=pre[i];
an[dep]=i;
if(i==head) {
head=nxt[i];
dfs(dep+1,sum+a[i],nxt[i]);
nxt[pre[i]]=i;
pre[nxt[i]]=i;
head=i;
}
else {
dfs(dep+1,sum+a[i],nxt[i]);
nxt[pre[i]]=i;
pre[nxt[i]]=i;
}
}
}
else {
int i=head;
nxt[pre[i]]=nxt[i];
pre[nxt[i]]=pre[i];
head=nxt[i];
an[dep]=i;
dfs(dep+1,sum+a[i],nxt[i]);
nxt[pre[i]]=i;
pre[nxt[i]]=i;
head=i;
}
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n*3;i++) {
scanf("%d",&a[i]);
nxt[i]=i+1,pre[i]=i-1;
}
sort(a+1,a+1+n*3);
dfs(1,0,1);
printf("%lld",ans);
return 0;
}
我加了一些优化,跑的很快
by thomaswmy @ 2022-08-16 14:13:58
优化是:
给木棍排序,这样搜第三根木棍时遇到第一个两边之和小于等于第三边就可退出
链表快速找下一个未放过的木棍
在搜第一根木棍时直接用最小的
by Dream__Sky @ 2022-08-16 14:15:16
@thomaswmy 感谢