发布时间:2025-12-10 19:18:27 浏览次数:9
18 校赛热身赛 C – Sometimes Naive (状态压缩)ProblemC.SometimesNaiveMr.FroggetstheNsticks,thelengthoftheithstickisAi.Hecanpidethesticksintooneormoregroups.Hewantedtoknowhowmanygroupsaremagicalatmost.Agroupi…
Problem C. Sometimes Naive
Mr.Frog gets the N sticks, the length of the ith stick is Ai. He can pide the sticks into one or moregroups. He wanted to know how many groups are magical at most.
A group is magical that needs to meet the following condition: there are three sticks in this group exactly,and the three sticks can form a triangle.
Input
The first line is an integer T, indicating the number of cases.
For each test case, the first line contains one integer N, where N is the number of stick.The second line contains N integers A1, A2, …, AN, where Ai is the length of the ith stick.
Output
For each test case, output one line containing “Case #x: y”, where x is the test case number (startingfrom 1) and y is the answer.
Limits
• 1 ≤ T ≤ 20.
• 1 ≤ N ≤ 20.
• 1≤Ai ≤2×109.
Example
standard input 是否还在为Ide开发工具频繁失效而烦恼,来吧关注以下公众号获取最新激活方式。亲测可用! 为防止网络爬虫,请关注公众号回复”口令”激活idea 激活CLion DataGrip DataSpell dotCover dotMemory dotTrace GoLand PhpStorm PyCharm ReSharper ReShaC++ Rider RubyMine WebStorm 全家桶 刷新【正版授权,激活自己账号】:Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛 【官方授权 正版激活】:官方授权 正版激活 自己使用,支持Jetbrains家族下所有IDE… | standard output |
| 3 | Case #1: 1Case #2: 0Case #3: 2 |
Note
For the first case, Mr.Frog can pide the sticks into a group {1, 1, 1} and it is magical, so you print 1.
For the second case, no matter how to pide the sticks, Mr.Frog can’t find any magical group, so youprint 0.
For the third case, Mr.Frog can pide the sticks into three groups {2, 3, 4}, {9, 17, 20} and {65}, thefirst and second group is magical, so you print 2.
题意:有n条边,求边不能重复使用的情况下最多能组成多少个三角形
判断能否构成三角形:两边之和大于第三边
可以先枚举一下构成一个三角形的所有情况 C(3,n) ,因为k个三角形可以由k-1个三角形加上1个无重边的三角形组成,然后逐个找下去,直到找不到有k个三角形时,答案为k-1个三角形。
主要的问题转化为如何判断是否有重复使用同一条边的情况,可以利用状态压缩,每条边有01两种状态,判断是否有重边只需要按位与一下判断结果是否>0即可
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 1<<21;int T,n,a[25],num[25],cas = 0;int b[N],vis[N];int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); if(n<3){ printf("Case #%d: 0\n",++cas); continue; } memset(num,0,sizeof num); memset(vis,0,sizeof vis); sort(a,a+n); int cnt = 0, mx = n/3; for(int i=0;i<n-2;i++){ for(int j=i+1;j<n-1;j++){ for(int k=j+1;k<n;k++){ if(a[k]-a[j]<a[i]){ int sum = (1<<i) + (1<<j) + (1<<k); b[cnt++] = sum; vis[sum] = 1; } } } } num[2] = cnt; for(int i=2;i<=mx;i++){ for(int j=num[i-1];j<num[i];j++){ for(int k=0;k<num[2];k++){ if((b[k]&b[j])>0||vis[b[k]+b[j]]) continue; vis[b[k]+b[j]] = 1; b[cnt++] = b[k]+b[j]; } } num[i+1] = cnt; } int ans = 0; for(int i=1;i<=mx;i++) if(cnt>num[i]) ans = i; printf("Case #%d: %d\n",++cas,ans); } return 0;}