xjoi题解:P7134数字牌
时间:1s 空间:256M
题目描述:
小信手上有 n+2 块数字牌,小友在上面写写画画,现在有 n 块数字牌,每块数字牌有正反两面,正面的数字为ai,反面为24−ai;另外两块数字牌,其中一块正面和反面的数字都是 0,另外一块正面和反面的数字都是 24 。
小信可以选择显示数字牌正反两面的任意一面,问 n+2 个数字牌中的数字,对于任意一种显示方案,计算任意两数之间差的绝对值的最小值,求所有方案中最小值的最大值。
输入格式:
第一行包含一个整数n,表示数字牌个数。
第二行包含 n 个整数a1,a2,...,an,表示每个数字牌的正面数字。
输出格式:
输出一个整数,表示答案。
样例1输入:
3
5 11 7
样例1输出:
5
样例2输入:
1
0
样例2输出:
0
约定与提示:
对于100%的数据,1≤n≤50;0≤ai≤12。
样例1解释:第1,2张牌都选正面,第3张牌选反面,三张牌变为 [5,11,17],答案是 min(5−0),(11−5),(17−11),(24−17)=5。
样例2解释:第1张牌选正面,答案是 min(0−0),(24−0)=0。
分析:
这道题就是选数字牌,它输入的数字牌是小于等于12,所以它输入的数字牌肯定是正面的,因为n<=50,那么2的50次方肯定是超的,如果正面一样的牌数量是>=3的,不管这样去组合,最小值的最大值肯定是0,理解できましたか?鸽笼问题呀!!!
代码:
#include<bits/stdc++.h>
using namespace std;
int b[150],a[150],sum[150],num[150];
int n,maxn=0;
void f()
{
sum[n+1]=24;
for(int i=1;i<=n+1;i++)
{
num[i]=sum[i];
}
sort(num+1,num+n+2);
int minn=num[1];
for(int i=1;i<=n;i++)
{
minn=min(minn,num[i+1]-num[i]);
}
maxn=max(maxn,minn);
return;
}
void dfs(int id)
{
if(id>n)
{
f();
return;
}
sum[id]=a[id];
dfs(id+1);
sum[id]=24-a[id];
dfs(id+1);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[a[i]]++;
}
b[0]+=2;
for(int i=0;i<=12;i++)
{
if(b[i]>=3)
{
cout<<0;
return 0;
}
}
for(int i=0;i<12;i++)
{
if(b[i]+b[i+1]>=3)
{
cout<<1;
return 0;
}
}
sort(a+1,a+1+n);
dfs(1);
cout<<maxn;
return 0;
}