您的位置:首页 > 编程语言 > Go语言

UVA 11054 Wine trading in Gergovia

2013-06-10 23:19 375 查看
我的思路刚开始就是从i开始找一直左右最近的需要酒的居民然后和他交易,很不幸的TLE了.

后来想了个方法用pre数组表示上一个需要酒的居民,nex表示下一个需要酒的居民,然后每次先按照pre找左边最近需要酒的居民和他交易,更新pre,如果左边没有居民需要了那就往右边找,更新nex,直到卖完酒.更新的时候如果v[i]==0表示这个居民不需要酒了,就while循环往上更新pre直到找到一个需要酒的居民或者碰到边界,nex同理.

用了2.766s,擦过..

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 100010;

int v[maxn], pre[maxn], nex[maxn], n;
void readInt(int & x){
x = 0;
char ch = getchar();
int sign = 1;
while(!(ch >= '0' && ch <= '9')){
if(ch == '-'){
sign = -1;
}
ch = getchar();
}
while (ch >= '0' && ch <= '9'){
x = x * 10 + (ch - '0');
ch =getchar();
}
x *= sign;
}
int main(){
while (scanf("%d", &n) && n){
int prei = -1, nexi = n;
long long ans = 0;
for (int i = 0; i < n; ++i){
readInt(v[i]);
pre[i] = prei;
if(v[i] > 0){
prei = i;
}
}
for (int i = n - 1; i >= 0; --i){
nex[i] = nexi;
if(v[i] > 0){
nexi = i;
}
}
for (int i = 0; i < n; ++i){
if(v[i] < 0){
int l = pre[i], r = nex[i];
while (v[i]){
while(l != -1 && !v[l]){
l = pre[l];
}
if(l != -1){
int t = -v[i];
int val = min(t, v[l]);
v[i] += val;
v[l] -= val;
while(v[l] == 0 && pre[l] !=  -1 && !v[pre[l]]){//压缩路径上去
pre[l] = pre[pre[l]];
}
ans += val * (i - l);
}else{
while (r != n && !v[r]){
r = nex[r];
}
int t = -v[i];
int val = min(t, v[r]);
v[i] += val;
v[r] -= val;
while(v[r] == 0 && nex[r] !=  n && !v[nex[r]]){
nex[r] = nex[nex[r]];
}
ans += val * (r - i);
}
}
}
}
printf("%lld\n", ans);
}
return 0;
}


后来找了下报告发现有扫描的方法 很巧妙.

想象下有一个人从0开始到n - 1一路走过去,见到卖酒的人收下来,见到买酒的就把身上的酒卖给他(如果身上没酒了就相当于负的,欠着).

答案的就是每个位置当前身上的携带或者欠的酒数量的和.

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 100010;

int V[maxn], n;

void readInt(int & x){
x = 0;
char ch = getchar();
int sign = 1;
while(!(ch >= '0' && ch <= '9')){
if(ch == '-'){
sign = -1;
}
ch = getchar();
}
while (ch >= '0' && ch <= '9'){
x = x * 10 + (ch - '0');
ch =getchar();
}
x *= sign;
}
int main(){
while (scanf("%d", &n) && n){
long long ans = 0;
int curWines = 0;
for (int i = 0; i < n; ++i){
readInt(V[i]);
}
for (int i = 0; i < n; ++i){
ans += abs(curWines);
curWines += V[i];
}
printf("%lld\n", ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: