Description
Input
有若干行,每行三个数字 X;Y;Z 代表一组数据,表示立方体的长宽高加 1
Output
第 i 行数据输出Case#i: 第i组数据的答案
Sample Input
2 1 2
2 2 2
Sample Output
Case #1: 4
Case #2: 15
HINT
x,y,z<=1000
Source
郑州培训D3考试题T2,Orzydc
大概是第一个正儿八经做的构造题吧…主要考察智商,像我这种智商低的自然是跪了233
题目可以转化为添加最少的边使原图构成一个欧拉路,满足有且仅有两个奇度点。
添加一个边可以消灭一对奇度点。
分类讨论……
一条链,显然添加0个。
平面的情况,奇度点只有可能是边上的点,看看边长奇偶性即可。
立体的情况,奇度点只有可能是六个面内和八个顶点,按每个面内的点数的奇偶性可以分为六偶、六奇、四偶两奇的情况
然后脑跑一下,有点蛋疼,挺烧脑的2333
六偶的情况:一个面拆出来四个点接上四个顶点,相对的面拆出两个点接顶点。
六奇的情况:每个面分一个点给一个顶点。
四偶两奇的情况:四个偶自己拼,两奇每个面分三个点给三个顶点。
神奇的是这三个的公式是一样的,求该如何理解QAQ
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
LL work(LL a,LL b,LL c)
{
LL tot = c * ((a - 1) * b + a * (b - 1)) + (c - 1) * a * b;
if(a == 1) //平面
{
if(b == 1 || (b == 2 && c == 2)) //一条链&&特判
return tot;
else if(b % 2 == 1 && c % 2 == 1) //两奇
return tot + b + c - 4;
else //两偶
return tot + b + c - 5;
}
else if(a == 2) //特判高为2和3,因为这样直接连顶点可能比顶点连面更优
return tot + (b - 2) * (c - 2) + 3;
else if(a == 3) //
{
if(b % 2 == 0 && c % 2 == 0) //六偶
return tot + (b - 2) * (c - 2) + (a - 2) * (b - 2) + (a - 2) * (c - 2) + 6;
else if(b % 2 == 1 && c % 2 == 1) //六奇
return tot + (b - 2) * (c - 2) + (a - 2) * (b - 2) + (a - 2) * (c - 2) + 9;
else //4偶2奇
return tot + (b - 2) * (c - 2) + (a - 2) * (b - 2) + (a - 2) * (c - 2) + 7;
}
else //很神奇的是,六偶和六奇还有4偶2奇的公式一样
return tot + (b - 2) * (c - 2) + (a - 2) * (b - 2) + (a - 2) * (c - 2) + 9;
}
LL num[10];
int main()
{
int T = 0;
while(~scanf("%lld%lld%lld",&num[1],&num[2],&num[3]))
{
sort(num + 1,num + 4);
printf("Case #%d: %lld\n",++ T,work(num[1],num[2],num[3]));
}
return 0;
}