我擦,这道题的代码写的那是一个纠结,写出来之后自己看着也是非常的搓。。这是道水题啊,还纠结了这么久,,太弱了。。。。。。
思路:由于只有1000个点,所以可以枚举,复杂度为(n*n),是可以过的。对于每个点,枚举去掉每条边后的值,取最小的即可。
ac代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <cmath>
using namespace std;
#define min(x,y) x<y ? x:y
#define max(x,y) x>y ? x:y
const int N = 1010;
int num[N],leftedge[N],rightedge[N],sum[N],ans[N];
void init()
{
memset(num,0,sizeof(num));
memset(leftedge,0,sizeof(leftedge));
memset(rightedge,0,sizeof(rightedge));
memset(sum,0,sizeof(sum));
memset(ans,0,sizeof(ans));
}
int main()
{
int numcase;
scanf("%d",&numcase);
for(int k = 1;k <= numcase;++k)
{
init();
int n;
scanf("%d",&n);
int total = 0;
for(int i = 1;i <= n;++i)
{
scanf("%d",&num[i]);
sum[i] = sum[i-1] + num[i];
total += num[i];
}
for(int i = 2;i <= n-1;++i)
{
leftedge[i] = i-1;
rightedge[i] = i;
}
leftedge[1] = n;
rightedge[1] = 1;
leftedge[n] = n-1;
rightedge[n] = n;
for(int i = 1;i <= n;++i)
{
int min = 100000000;
for(int j = 1;j <= n;++j)
{
if(j == leftedge[i] || j == rightedge[i])
{
ans[i] = total - num[j];
if(ans[i]<min)
{
min = ans[i];
}
}
else
{
int x;
if(j > i)
x=fabs(sum[j-1] - sum[i-1]);
else
x=fabs(sum[j] - sum[i-1]);
int y=total - x - num[j];
int mi = min(x,y);
int ma = max(x,y);
ans[i] = total - num[j] + mi;
if(ans[i] < min && ans[i] > 0)
{
min = ans[i];
}
}
}
ans[i] = min;
}
printf("Case #%d: ",k);
for(int i = 1;i < n;++i)
{
printf("%d ",ans[i]);
}
printf("%d",ans[n]);
puts("");
}
return 0;
}