Piece of cake!
Piece of cake!
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByte
Total Submit: 77 Accepted: 6
Description
This morning Aunt Petunia baked a cake. The cake had the shape of a box with dimensions A × B × C centimeters.
During the day, each of the D kids in the neighborhood stopped by for a slice of the cake. Every time a kid came for some cake, Aunt Petunia took her knife and made a single cut parallel to one of the sides of the cake. The piece she cut off the cake was always exactly 1 cm thick.
Given the values A, B, C, and D, compute the largest possible volume the cake could have at the end of the day.
Input
The first line of the input file contains an integer T specifying the number of test cases. Each test case is preceded by a blank line.
Each test case consists of a single line containing the integers A, B, C, and D.
You may assume that 0 < A,B,C ≤ 1018 and 0 ≤ D ≤ A + B + C − 3.
Output
For each test case output a single line with a single integer: the largest possible volume of the rest of the cake, after each of the kids got a slice. You may assume that for each test case the answer will conveniently fit into a 64-bit signed integer variable.
Sample Input
3 4 5 6 0 4 5 6 3 1 1 10 9
Sample Output
120 64 1
Hint
One way of optimally solving the second test case: first make two cuts parallel to the 4 × 5 side to obtain a 4×5×4 cake, and then make a cut parallel to the current 4×4 side to obtain a cube with side 4 cm long.
分析:
题目问我们如何切才能使剩下的蛋糕最大,我想了一下感觉只需要先切最长的一条边直到d==0或者最长的那条边和第二长的一条边相等为止;如果最长的有两条边那么同时切这两条边,直到d==1||d==0或者三条边都相等为止;如果三条边都相等,则同时切这三条边直到d==1 ||d==2||d==0为止;大体的思路就是这样。但是也不知道自己的代码哪里有问题,交上去一直是TLE(Time Limit Exceeded),我自己估计是出现的死循环,可是一直就是找不出。
自己的代码如下(TLE):

#include<stdio.h>
#include<stdlib.h>
__int64 a[10],d;
int cmp(const void *a, const void *b)
{
return (int)(*(__int64*)b-*(__int64*)a);
}
__int64 min(__int64 a, __int64 b)
{
return a<b ? a : b;
}
void divide()
{
while (d)
{
qsort(a, 3, sizeof(a[0]), cmp);
// printf("%I64d %I64d %I64d\n", a[0], a[1], a[2]);
if (a[0]==a[1] && a[0]==a[2]) //三条边都相等
{
__int64 tmp=d/3;
d%=3;
a[0]-=tmp; a[1]-=tmp; a[2]-=tmp;
if (d==2)
{
d-=2;
a[0]-=1;
a[1]-=1;
}
else if (d==1)
{
d-=1;
a[0]-=1;
}
}
else if (a[0]==a[1] && a[0]>a[2]) //只有两条长边相等
{
__int64 tmp=min(a[0]-a[2], d/2);
d-=tmp*2;
a[0]-=tmp;
a[1]-=tmp;
if (d==1)
{
d-=1; a[0]-=1;
}
}
else //三条边都不想等
{
__int64 tmp=min(a[0]-a[1], d);
d-=tmp;
a[0]-=tmp;
}
}
}
int main()
{
int n;
scanf("%d", &n);
while (n--)
{
scanf("%I64d%I64d%I64d%I64d", &a[0],&a[1],&a[2],&d);
divide(); //printf("%I64d %I64d %I64d\n", a[0], a[1], a[2]);
printf("%I64d\n", a[0]*a[1]*a[2]);
}
return 0;
}

#include <stdio.h>
void swap(__int64 &a, __int64 &b)
{
__int64 temp = a;
a = b;
b = temp;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
__int64 a, b, c, d;
__int64 sum;
scanf("%I64d %I64d %I64d %I64d", &a, &b, &c, &d);
if(a > b) swap(a, b);
if(a > c) swap(a, c);
if(b > c) swap(b, c); //先对三个数从小到大排序
sum = b + c - 2*a; //求切到三条边都相等需要几次
if(d >= sum) //判断能不能切到三条边都相等
{
d -= sum;
__int64 p = d%3;
a -= d/3; //切完以后三条边的长度都等于a;
if(a <= 0) printf("0\n");
else
{
if(p == 0)
printf("%I64d\n", a*a*a);
else if(p == 1)
printf("%I64d\n", a*a*(a-1));
else if(p == 2)
printf("%I64d\n", a*(a-1)*(a-1));
}
}
else
{
sum = c - b;
if(d >= sum) //判断能不能切到两条边都相等
{
d -= sum;
__int64 p = d%2;
b -= d/2;
if(p == 0)
printf("%I64d\n", a*b*b);
else if(p == 1)
printf("%I64d\n", a*b*(b-1));
}
else printf("%I64d\n", a*b*(c - d)); //三条边都不可能切到相等
}
}
return 0;
}