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,擦过..
后来找了下报告发现有扫描的方法 很巧妙.
想象下有一个人从0开始到n - 1一路走过去,见到卖酒的人收下来,见到买酒的就把身上的酒卖给他(如果身上没酒了就相当于负的,欠着).
答案的就是每个位置当前身上的携带或者欠的酒数量的和.
后来想了个方法用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); } }
相关文章推荐
- UVa 11054 - Wine trading in Gergovia
- UVa 11054 Wine trading in Gergovia(扫描)
- UVa 11054 - Wine trading in Gergovia
- uva 11054 - Wine trading in Gergovia
- UVa 11054 - Wine trading in Gergovia
- uva 11054 Wine trading in Gergovia (贪心 + 模拟)
- uva 11054 wine trading in gergovia (归纳【好吧这是我自己起的名字】)——yhx
- UVa11054 poj2940 sdut2370 Wine trading in Gergovia(贪心)
- (UVA - 11054)Wine trading in Gergovia (等价转换)
- UVa11054 Wine trading in Gergovia(贪心+思路)
- UVa 11054 - Wine trading in Gergovia(扫描法 水题)
- UVa11054 - Wine trading in Gergovia UVA
- UVa 11054 - Wine trading in Gergovia (等价转化_水题吧)
- UVA11054_Wine trading in Gergovia
- UVA 11054 Wine trading in Gergovia
- UVA 11054 Wine trading in Gergovia (酒的交易问题)
- Uva 11054 Wine trading in Gergovia(贪心模拟)
- UVA - 11054 Wine trading in Gergovia 扫描法
- Wine trading in Gergovia UVA - 11054 贪心思维
- UVa 11054 Wine trading in Gergovia