您的位置:首页 > 其它

HDU 5203 Rikka with wood sticks 分类讨论

2016-04-18 15:14 344 查看

题目链接:

hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5203

bc(chinese):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=575&pid=1002

题解:

不断的分类讨论下去

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;

const int maxn=1000+10;
const int INF=0x3f3f3f3f;
typedef long long LL;

int n,m;

int main(){
while(scanf("%d%d",&n,&m)==2&&n){
//找出bad stick的左右界限
int beg=INF,end=-1;
for(int i=0;i<m;i++){
int x;
scanf("%d",&x);
beg=min(beg,x);
end=max(end,x);
}
int l1=beg-1,l2=n-end;
if(l1>l2) swap(l1,l2);
LL ans=0;

if(l1>0){
//截取的bad stick段在中间
for(int i=1;i<l2;i++){
int a=l1,b=i,c=l2-i;
if(a+b>c&&a+c>b&&b+c>a) ans++;
}
}else{
//截取的bad stick段在两边
for(LL x=(l2+2)/3;x<(l2+1)/2;x++){
//枚举最长边为x的情况
LL tmp=3*x+1-l2,cnt=0;//tmp代表第一条边为x时的所有合法的情况(后两条边有考虑顺序,第一条边不考虑顺序)
if(l2-2*x>0){
//最长边有可能存在两条的情况
if(l2-2*x==x){
//三条边相等(x,x,x)
cnt=(tmp-1)*3+1;
}else{
if(((l2-x)&1)==0){
//有两条边相等的情况(1、x,x,a(a<x);2、x,a,a(a<x))
cnt=(tmp-3)*3+3*1+3*1;
}else{
//(x,x,a)
cnt=(tmp-2)*3+3*1;
}
}
}else{
//最长边不可能存在两条的情况
if(((l2-x)&1)==0){
//( x,a,a)
cnt=(tmp-1)*3+3*1;
}else{
//(x,b,a(b!=a))
cnt=tmp*3;
}
}
ans+=cnt;
}
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: