中南
Altruistic Amphibians
Description
A set of frogs have accidentally fallen to the bottom of a large pit. Their only means of escaping the pit is to jump out of it. Each frog i is described by three parameters (li, wi, hi) where li is its leap capacity, wi its weight, and hi its height. The leap capacity specifies how high that frog can jump. If a frog's leap capacity is strictly larger than the depth of the pit, the frog can directly escape the pit. However, these frogs are altruistic. Rather than selfishly saving themselves and leaving the frogs with too limited leap capacity behind, they collectively aim to save as many of them from the pit as possible.
The frogs realize that if a frog A climbs up on the back of frog B before it jumps, the first frog A stands a better chance of escaping the pit: it can escape if hB + lA is strictly larger than the depth of the pit.
Furthermore, if frog B carrying frog A on its back climbs up on the back of frog C, the situation is even better for frog A: it can now escape the pit if hC + hB + lA is strictly larger than the depth of the pit.
The frogs can build even higher piles of frogs this way, the only restriction is that no frog may carry other frogs of weight in total amounting to its own weight or heavier. Once a pile has been used to allow a frog to escape, the frogs in the pile jump back to the bottom of the pit and they can then form a new pile (possibly consisting of a different set of frogs). The question is simply how many frogs can escape the pit assuming they collaborate to maximize this number?
Input
The first line of input contains two integers n and d (1 ≤ n ≤ 100 000, 1 ≤ d ≤ 108), where n is the number of frogs and d is the depth of the pit in µm. Then follow n lines each containing three integers l, w, h (1 ≤ l, w, h ≤ 108), representing a frog with leap capacity l µm, weight w µg, and height h µm. The sum of all frogs' weights is at most 108 µg.
Output
Output the maximum number of frogs that can escape the pit.
Sample Input
3 19 15 5 3 12 4 4 20 10 5
Sample Output
3
Hint
Source
这个昨天写了
#include <cstring> #include <cstdlib> #include <cstdio> #include <string> #include <cmath> #include <algorithm> #include <queue> #include <iostream> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int mx = 1e5 + 10; struct node { int l, w, h; }exa[mx]; bool cmp(node a,node b) { return a.w > b.w; } const int maxn = 1e8 + 10; int dp[maxn]; int main() { int n, d; cin >> n >> d; for(int i=0;i<n;i++) { cin >> exa[i].l >> exa[i].w >> exa[i].h; } int ans = 0; sort(exa , exa + n, cmp); for(int i=0;i<n;i++) { int w = exa[i].w; if (exa[i].l + dp[w] > d) ans++; for(int j=1;j<min(w,maxn-w);j++) { dp[j] = max(dp[j], dp[j + w] + exa[i].h); } } cout << ans << endl; return 0; }
Baby Bites
Description
Arild just turned 1 year old, and is currently learning how to count. His favorite thing to count is how many mouthfuls he has in a meal: every time he gets a bite, he will count it by saying the number out loud.
Unfortunately, talking while having a mouthful sometimes causes Arild to mumble incomprehensibly, making it hard to know how far he has counted. Sometimes you even suspect he loses his count! You decide to write a program to determine whether Arild's counting makes sense or not.
Input
The first line of input contains an integer n (1 ≤ n ≤ 1 000), the number of bites Arild receives. Then second line contains n space-separated words spoken by Arild, the i'th of which is either a non-negative integer ai (0 ≤ ai ≤ 10 000) or the string "mumble
".
Output
If Arild's counting might make sense, print the string "makes sense". Otherwise, print the string "something is fishy".
Sample Input
5 1 2 3 mumble 5 -------------------------------------------------- 8 1 2 3 mumble mumble 7 mumble 8 --------------------------------------------------- 3 mumble mumble mumble
Sample Output
makes sense --------------------------------------------------- something is fishy --------------------------------------------------- makes sense
Hint
Source
ncpc2018
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #define inf 0x3f3f3f3f using namespace std; int main() { int n,flag=0; char s[1010]; cin >> n; for (int i = 1; i <= n; i++) { cin >> s; if (s[0] == 'm') continue; int len = strlen(s),x=0; for (int i = 0; i < len ; i++) { x = x * 10 + s[i] - '0'; } if (x != i) flag = 1; } if (!flag) printf("makes sense\n"); else printf("something is fishy\n"); return 0; } /********************************************************************** Problem: 2250 User: echozhou Language: C++ Result: AC Time:4 ms Memory:2024 kb **********************************************************************/
Code Cleanups
Description
The management of the software company JunkCode has recently found, much to their surprise and disappointment, that productivity has gone down since they implemented their enhanced set of coding guidelines. The idea was that all developers should make sure that every code change they push to the master branch of their software repository strictly follows the coding guidelines. After all, one of the developers, Perikles, has been doing this since long before these regulations became effective so how hard could it be?
Rather than investing a lot of time figuring out why this degradation in productivity occurred, the line manager suggests that they loosen their requirement: developers can push code that weakly violates the guidelines as long as they run cleanup phases on the code from time to time to make sure the repository is tidy.
She suggests a metric where the "dirtiness" of a developer's code is the sum of the pushes that violate the guidelines -- so-called dirty pushes -- made by that developer, each weighted by the number of days since it was pushed. The number of days since a dirty push is a step function that increases by one each midnight following the push. Hence, if a developer has made dirty pushes on days 1, 2, and 5, the dirtiness on day 6 is 5+4+1=10. She suggests that a cleanup phase, completely fixing all violations of the coding guidelines, must be completed before the dirtiness reaches 20. One of the developers, Petra, senses that this rule must be obeyed not only because it is a company policy. Breaking it will also result in awkward meetings with a lot of concerned managers who all want to know why she cannot be more like Perikles? Still, she wants to run the cleanup phase as seldomly as possible, and always postpones it until it is absolutely necessary. A cleanup phase is always run at the end of the day and fixes every dirty push done up to and including that day. Since all developers are shuffled to new projects at the start of each year, no dirtiness should be left after midnight at the end of new year's eve.
Input
The first line of input contains an integer n (1 ≤ n ≤ 365), the number of dirty pushes made by Petra during a year. The second line contains n integers d1, d2, …, dn (1 ≤ di ≤ 365 for each 1 ≤ i ≤ n) giving the days when Petra made dirty pushes. You can assume that di < dj for i < j.
Output
Output the total number of cleanup phases needed for Petra to keep the dirtiness strictly below 20 at all times.
Sample Input
5 1 45 65 84 346 -------------------------------------------------- 3 310 330 350
Sample Output
4 --------------------------------------------------- 3
Hint
Source
ncpc2018
这个题目大意:
就是清理垃圾,如果第i天产生垃圾,那么会从第i+1天才开始累加,然后每一天的垃圾数严格小于20,问你最少清理多少次垃圾。
这个题目就是一个模拟。
#include <cstring> #include <cstdlib> #include <cstdio> #include <string> #include <cmath> #include <algorithm> #include <queue> #include <iostream> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn = 1e5 + 10; int vis[490]; int main() { int n; int num = 0; cin >> n; memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) { int x; cin >> x; vis[x] = 1; } int ans = 0; int sum = 0; for (int i = 1; i <= 366 ; i++) { sum += num; if (sum == 19) { sum = 0; ans++; num = 0; continue; } if (sum > 19) { sum = 0; num = 0; ans++; } if (vis[i]) num++; } if (sum > 0) ans++; cout << ans << endl; return 0; } /********************************************************************** **********************************************************************/
#include <cstring> #include <cstdlib> #include <cstdio> #include <string> #include <cmath> #include <algorithm> #include <queue> #include <iostream> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn = 1e5 + 10; int vis[490]; int main() { int n; int num = 0; cin >> n; memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) { int x; cin >> x; vis[x] = 1; } int ans = 0; int sum = 0; for (int i = 1; i <= 365; i++) { if (vis[i]) num++; sum += num; if(sum>=20) { ans++; sum = 0; num = 0; } } if (sum > 0) ans++; cout << ans << endl; return 0; } /********************************************************************** Problem: 2251 User: echozhou Language: C++ Result: AC Time:4 ms Memory:2020 kb **********************************************************************/
House Lawn
Description
You have just bought a new house, and it has a huge, beautiful lawn. A lawn that needs cutting. Several times. Every week. The whole summer.
After pushing the lawnmower around the lawn during the hottest Saturday afternoon in history, you decided that there must be a better way. And then you saw the ads for the new robotic lawnmovers. But which one should you buy? They all have different cutting speeds, cutting times and recharge times, not to mention different prices!
According to the advertisement, a robotic lawnmover will spend all its time either cutting the lawn or recharging its battery. Starting from a full battery, it will cut the lawn at a given rate of c square meters per minute for a cutting time of t minutes, after which it has run out of battery. Once out of battery, it will immediately start recharging. After recharging for r minutes the battery is full again and it immediately starts cutting.
You decide that in order for your lawn to look sufficiently prim and proper, the lawnmower that you buy must be powerful enough to cut your whole lawn at least once a week on average. Formally, if we start the mower fully charged at the beginning of the week and run it for exactly T weeks, it needs to cut the whole lawn at least T times, for all positive integers T. But apart from this, you have no specific requirements, so among the ones that satisfy this requirement, you will simply go for the cheapest option. For the purposes of cutting your lawn, you may make the simplifying assumption that a week is always exactly 10 080 minutes long.
Input
The first line of input contains two integers ℓ and m (1 ≤ ℓ ≤ 106, 1 ≤ m ≤ 100), the size of your lawn in square meters, and the number of lawnmowers to consider, respectively.
Then follow m lines, each containing a string n and 4 integers p, c, t, and r, separated by commas, describing a lawnmower as follows:
-
n is the name of the lawnmower, a string of at most 60 printable characters (ASCII 32 to 126) excluding '
,
', neither starting nor ending with a space, -
1 ≤ p ≤ 100 000 is the price of the lawnmover,
-
1 ≤ c ≤ 100 is the cutting rate in square meters per minute,
-
1 ≤ t ≤ 10 080 is the cutting time in minutes, and
-
1 ≤ r ≤ 10 080 is the recharge time in minutes.
Output
Output the name of the cheapest lawnmower capable of cutting your whole yard at least once a week on average. If several lawnmovers share the same lowest price, output all of their names, in the same order they were given in the input. If there is no such mower, output "no such mower
".
Sample Input
7000 4 Grass Slayer 2000,9999,10,120,120 Slow-Mowe,999,1,120,240 Eco-cut X2,5499,2,25,35 Mowepower,5499,3,25,35 ------------------------------------------ 100000 4 Grass Slayer 2000,9999,10,120,120 Slow-Mowe,999,1,120,240 Eco-cut X2,5499,2,25,35 Mowepower,5499,3,25,35
Sample Output
Eco-cut X2 Mowepower ----------------------------------- no such mower
Hint
Source
ncpc2018
大意:
就是让你选一个除草机,然后给你这个除草机的名字价格效率工作时间充电时间,然后唯一的要求就是一个星期里面,除草的面积大于给定的面积
这个题目是一个模拟题,首先你要处理好这个数据的输入,然后就是求除给定的面积这么大的地方的时间,如果小于10080那就取比较价格。
这个有一个比较坑的地方,就是不一定要充满电才可以用。
#include <cstring> #include <cstdlib> #include <cstdio> #include <string> #include <cmath> #include <algorithm> #include <queue> #include <iostream> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn = 110; int n, m; struct node { int id, mon, c, t, r; double ed; string a; }exa[maxn]; string b; bool cmp(node a,node b) { if (a.mon == b.mon) return a.id < b.id; return a.mon < b.mon; } const int tim = 10080; bool isok(int x) { int all = exa[x].c*exa[x].t; double ti = n * 1.0 / all * (exa[x].r + exa[x].t); exa[x].ed = ti; return ti <= tim; } int main() { cin >> n >> m; getchar(); for (int j = 1; j <= m; j++) { getline(cin, b); exa[j].id = j; int flag = 1; int len = b.size(); for(int i=0;i<len;i++) { if(b[i]!=','&&flag==1) { exa[j].a += b[i]; } else if(b[i]!=','&&flag==2) { exa[j].mon = exa[j].mon * 10 + b[i] - '0'; } else if(b[i]!=','&&flag==3) { exa[j].c = exa[j].c * 10 + b[i] - '0'; } else if(b[i]!=','&&flag==4) { exa[j].t = exa[j].t * 10 + b[i] - '0'; } else if(b[i]!=','&&flag==5) { exa[j].r = exa[j].r * 10 + b[i] - '0'; } else flag++; //cout << flag << endl; } //cout << exa[j].a; //printf(" %d %d %d %d\n", exa[j].mon, exa[j].c, exa[j].t, exa[j].r); } sort(exa + 1, exa + 1 + m, cmp); int ans = inf; for(int i=1;i<=m;i++) { if(isok(i)) { ans = min(ans, exa[i].mon); } } if(ans>=inf) { printf("no such mower\n"); return 0; } for(int i=1;i<=m;i++) { if (exa[i].mon == ans&&exa[i].ed<=tim) cout << exa[i].a << endl; } return 0; } /********************************************************************** Problem: 2256 User: echozhou Language: C++ Result: AC Time:4 ms Memory:2040 kb **********************************************************************/
2257: Intergalactic Bidding
Description
Today the Intergalactic Council of Pebble Coins (ICPC) conducted an intergalactic auction of the Neutronium Chaos Pebble Coin (NCPC). This coin, which was forged in the Ancient Coin Machine (ACM), is rumored to be the key to ruling the universe.
Due to the extremely competitive nature of the auction, as well as the odd mechanics of the intergalactic currency used (far too advanced for mere mortals to understand), the auction was conducted with the following rules:
-
only one participant was allowed to make a bid at a time,
-
each participant was only allowed to make one bid, and
-
a participant making a bid had to bid at least twice the amount of the highest bid at the time.
The first participant making a bid was allowed to make a bid of any positive amount.
After the auction there were a lot of sore losers -- understandably, having just lost their chance at world domination. To make the losers feel a little better and prevent possible rioting, the ICPC has decided to hold a lottery for the participants. The winners of the lottery are determined as follows. The ICPC picks a random number s. A group of participants is called winning if the sum of their bets from the auction is equal to s. A participant wins the lottery and receives a prize -- a shiny Pebble Coin -- if they belong to any winning group of participants.
Given the names of the participants, the bets that they made, and the random number s chosen by the ICPC, help them determine which participants won the lottery.
Input
The first line of input contains two integers n and s, where 1 ≤ n ≤ 1 000 is the number of participants, and 1 ≤ s < 101 000 is the random number chosen by the ICPC.
Then follow n lines describing the participants. Each line contains a string t and an integer b, where t is the name of a participant, and 1 ≤ b < 101 000 is the amount of his bet. The name of each participant is unique and consists of between 1 and 20 letters from the English alphabet.
Output
Output an integer k denoting the number of participants that won the lottery. Then output k lines containing the names of the participants that won the lottery, one per line, in any order.
Sample Input
5 63 Vader 3 Voldemort 7 BorgQueen 20 Terminator 40 Megatron 101 --------------------------- 4 1112 Blorg 10 Glorg 1000 Klorg 1 Zlorg 100
Sample Output
3 BorgQueen Terminator Vader --------------------- 0
Hint
Source
ncpc2018
大意:
首先这个是一个大数,其次这个他们下的赌注有大于等于2倍的关系,
所以呢,如果第一个是n,那么第二个小于等于1/2n,1/4n,1/8n....
这个就说明之后的所有的数加起来都不会大于n,所以如果大于n但是不减去这个n,那么这个数就无法归零。
所以解法就是:
先大数读入,然后对赌注排序,然后就是大数减法。
//大数 #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <algorithm> #include <iostream> #include <queue> using namespace std; struct bigint { int s[10100]; int len; bool zf; bigint() { memset(s, 0, sizeof(s)); len = 0; zf = 0; } void init(char *ch)//把字符串转化成数字 { len = strlen(ch); if (ch[1] == '-') { zf = 1; for (int i = 2; i <= len; i++) s[i] = ch[len - i] - '0'; } else { for (int i = 1; i <= len; i++) { s[i] = ch[len - i] - '0'; //printf("s[%d]=%d\n", i, s[i]); } } } void reverse()//前后倒置 { int t[10010]; for (int i = 1; i <= len; i++) t[i] = s[len - i + 1]; for (int i = 1; i <= len; i++) s[i] = t[i]; } void uni()//? { while (s[len] == 0 && len > 1)len--; } void pr()//打印 { for (int i = len; i >= 1; i--) printf("%d", s[i]); } }; bigint operator +(bigint x, bigint y)//大数+ { bigint nw; nw.len = max(x.len, y.len); for (int i = 1; i <= nw.len; i++) { nw.s[i] += x.s[i] + y.s[i]; nw.s[i + 1] += nw.s[i] / 10; nw.s[i] %= 10; } if (nw.s[nw.len + 1] > 0) nw.len++; return nw; } bool operator >(bigint x, bigint y)//大数> { if (x.len > y.len) return 1; if (x.len < y.len) return 0; int nw = x.len; while (nw) { if (x.s[nw] > y.s[nw]) return 1; else if (x.s[nw] < y.s[nw]) return 0; nw--; } if (nw == 0) return 1; return 1; } bool operator <(bigint x, bigint y)//大数> { if (x.len > y.len) return 0; if (x.len < y.len) return 1; int nw = x.len; while (nw) { if (x.s[nw] > y.s[nw]) return 0; else if (x.s[nw] < y.s[nw]) return 1; nw--; } if (nw == 0) return 0; return 0; } bigint operator -(bigint x, bigint y)//大数- { bigint nw; nw.len = max(x.len, y.len); for (int i = 1; i <= nw.len; i++) { nw.s[i] += x.s[i] - y.s[i]; if (nw.s[i] < 0) nw.s[i + 1]--, nw.s[i] += 10; } while (nw.s[nw.len] == 0 && nw.len > 0)nw.len--; return nw; } bigint operator *(bigint x, bigint y)//大数* { bigint nw; nw.len = x.len + y.len; for (int i = 1; i <= x.len; i++) for (int j = 1; j <= y.len; j++) { nw.s[i + j - 1] += x.s[i] * y.s[j]; nw.s[i + j] += nw.s[i + j - 1] / 10; nw.s[i + j - 1] %= 10; } while (nw.s[nw.len] == 0 && nw.len > 0)nw.len--; return nw; } bigint operator /(bigint x, int y)//高精度除低精度 { bigint sh; int nv = 0; for (int i = 1; i <= x.len; i++) { nv = nv * 10 + x.s[i]; sh.s[++sh.len] = nv / y; nv = nv % y; } return sh; } struct node { char a[1010]; bigint x; bool operator<(const node &a)const { return a.x < x; } }exa[1010]; const int maxn = 1e5 + 10; char a[maxn]; int main() { int n; bigint s; cin >> n >> a; s.init(a); for(int i=1;i<=n;i++) { cin >> exa[i].a >> a; exa[i].x.init(a); } sort(exa + 1, exa + 1 + n); int ans[1010], pos = 0; for(int i=1;i<=n;i++) { if(s>exa[i].x) { s = s - exa[i].x; ans[pos++] = i; } } if (s.len != 0) pos = 0; cout << pos << endl; for (int i = 0; i < pos; i++) cout << exa[ans[i]].a << endl; return 0; }
2258: Jumbled String
Description
Recall that a subsequence of a string is any string obtained by removing some subset of characters from the string, for instance "string", "sing", "i" and "sg" are all subsequences of "string". If the same subsequence can be obtained in exactly t different ways, by removing different subsets of characters, we say that the subsequence occurs t times.
Jingfei wants to create a nonempty bit string that has the following properties:
-
the subsequence
00
occurs a times, -
the subsequence
01
occurs b times, -
the subsequence
10
occurs c times, and -
the subsequence
11
occurs d times.
However, Jingfei does not know how to create such a string -- or whether it is even possible. Could you help her?
Input
he input consists of a single line with four integers a, b, c, and d (0 ≤ a, b, c, d ≤ 109).
Output
Output a bit string that satisfies the given requirements. If there are several solutions, output any one of them. If there are no solutions, output "impossible
".
Sample Input
3 4 2 1 --------------------- 5 0 0 5
Sample Output
01001 --------------------- impossible
Hint
Source
ncpc2018
大意:
就是给你a,b,c,d a代表00的数目,b代表01的数目,c代表10的数目,d代表11的数目
然后让你用01一个序列表示,如果不存在就输出impossible
这个题目有一个小规律,就是01的数目+10的数目是恒定的。
然后就可以写了
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <string> #include <cmath> #include <iostream> using namespace std; typedef long long ll; const ll maxn = 1e10; const double eps = 1e10 - maxn; int main() { ll a, b, c, d; cin >> a >> b >> c >> d; if (a + b + c + d == 0) { printf("0\n"); return 0; } ll x = (1 + sqrt(1 + 8 * a)) / 2;//代表0的个数 ll y = (1 + sqrt(1 + 8 * d)) / 2;//代表1的个数 if (x*(x-1)/2!=a||y*(y-1)/2!=d) { printf("impossible\n"); return 0; } if(a==0&&d==0) { if (b == 1 && c == 0) printf("01\n"); else if (b == 0 && c == 1) printf("10\n"); else printf("impossible\n"); return 0; } if(b==0&&c==0) { if (a == 0) for (int i = 1; i <= y; i++) printf("1"); else if (d == 0) for (int i = 1; i <= x; i++) printf("0"); else printf("impossible"); printf("\n"); return 0; } if(b+c!=x*y) { printf("impossible\n"); return 0; }//c是 10的个数 b是01的个数 x是0的个数 y是1的个数 ll num = c / x;//有多少个1要放在最前面 ll res = c % x;//一个1穿插在res个0前面,其余1都在最后面 int flag = 0; if (res) flag = 1; for (int i = 0; i < num; i++) printf("1"); for (int i = 0; i < x - res; i++) printf("0"); if (flag) printf("1"); for (int i = 0; i < res; i++) printf("0"); for (int i = 0; i < y - num - flag; i++) printf("1"); printf("\n"); return 0; } /********************************************************************** Problem: 2258 User: echozhou Language: C++ Result: AC Time:12 ms Memory:2036 kb **********************************************************************/
2252: Delivery Delays
Description
Hannah recently discovered her passion for baking pizzas, and decided to open a pizzeria in downtown Stockholm. She did this with the help of her sister, Holly, who was tasked with delivering the pizzas. Their pizzeria is an instant hit with the locals, but, sadly, the pizzeria keeps losing money. Hannah blames the guarantee they put forth when they advertised the pizzeria:
Do you have a craving for a delicious pizza? Do you want one right now? Order at Hannah's pizzeria and we will deliver the pizza to your door. If more than 20 minutes elapse from the time you place your order until you receive your Hannah's pizza, the pizza will be free of charge!
Even though Holly's delivery car can hold an arbitrary number of pizzas, she has not been able to keep up with the large number of orders placed, meaning they have had to give away a number of pizzas due to late deliveries.
Trying to figure out the best way to fix the situation, Hannah has now asked you to help her do some analysis of yesterday's orders. In particular, if Holly would have known the set of orders beforehand and used an optimal delivery strategy, what is the longest a customer would have had to wait from the time they placed their order until they received their pizza?
Hannah provides you with a map of the roads and road intersections of Stockholm. She also gives you the list of yesterday's orders: order i was placed at time si from road intersection ui, and the pizza for this order was out of the oven and ready to be picked up for delivery at time ti. Hannah is very strict about following the "first come, first served" principle: if order i was placed before order j (i.e. si < sj), then the pizza for order i will be out of the oven before the pizza for order j (i.e. ti < tj), and the pizza for order i must be delivered before the pizza for order j.
Input
The first line of input contains two integers n and m (2 ≤ n ≤ 1 000, 1 ≤ m ≤ 5 000), where n is the number of road intersections in Stockholm and m is the number of roads. Then follow m lines, the i'th of which contains three integers ui, vi and di denoting that there is a bidirectional road between intersections ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi), and it takes Holly's delivery car di time units to cross this road in either direction (0 ≤ di ≤ 108). There is at most one road between any pair of intersections.
Then follows a line containing an integer k, the number of orders (1 ≤ k ≤ 1 000). Then follow k lines, the i'th of which contains three integers si, ui, ti denoting that an order was made at time si from road intersection ui (2 ≤ ui ≤ n), and that the order is ready for delivery at time ti (0 ≤ si ≤ ti ≤ 108). The orders are given in increasing order of when they were placed, i.e. si < sj and ti < tj for all 1 ≤ i < j ≤ k.
Hannah's pizzeria is located at road intersection 1, and Holly and her delivery car are stationed at the pizzeria at time 0. It is possible to reach any road intersection from the pizzeria.
Output
Output a single integer denoting the longest time a customer has to wait from the time they place their order until the order is delivered, assuming that Holly uses a delivery schedule minimizing this value.
Sample Input
4 4 1 2 2 2 3 4 3 4 1 4 1 2 3 1 4 2 3 3 3 4 3 6 ---------------------------- 3 2 1 2 1 3 2 2 4 0 3 1 1 3 3 2 2 4 4 3 6
Sample Output
6 ----------------------- 8
Hint
1--2--2
| |
2 4
| |
4--1--3
3: take pizzas 1, 2
5: deliver pizza 1 (4)
6: deliver pizza 2 (3)
9: take pizza 3
11: deliver pizza 3 (7)
6: take pizzas 1,2,3
8: deliver pizza 1 (7)
9: deliver pizza 2,3 (6,5)
2: take pizza 1
4: deliver pizza 1 (3)
6: take pizza 2,3
9: deliver pizza 2,3 (6,5)
Source
ncpc2018
NCPC2018 Delivery Delays
这个题目要冷静分析!!!
先分析一下题目给的条件,题目说的是一家披萨店送披萨,给你送披萨的地图,还有每一个订单的时间和送达的地点
还有就是披萨出锅的时间,题目要求先到先得,就是订单越靠前就必须先送。
题目中给你的订单时间和出锅时间严格增加,让你求客户等待的最长时间的最小值。
这个题目首先要用到dij,其次应该要用到二分求等待最长时间的最小值。这个就是求最后一个人就是k
收到披萨的时间就可以了。
然后还要一个dp数组来记录到每一个点最短的时间。
所以这个就可以分成三个部分
第一个:就是用dis数组存储任意两个点之间的距离,跑n次dij即可
第二个就是算dp数组,这个就是根据二分枚举的每一个x来考虑,
因为这个订单可以一起送也可以分开送,所以就模拟一下这个过程,
如果第i个订单和i+1个订单一起送,首先我们可以判定就是dp[i]不会变小,所以这个时候就只要
去更新dp[i+1]即可,
这个时候情况会很多,我们可以所有的一起送,也可以选一部分一起送,所以对于每一个i我们都要考虑它和后面的一起送
这种情况,这样表述的不是很清楚,不过一些小细节可以自己思考思考。
第三个就是二分了,这个就是去枚举x等待的最长时间
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <queue> #include <algorithm> #include <vector> #include <string> #define inf 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; ll n, m, k; ll dp[1010]; ll dis[1010][1010]; struct node { ll to, dist; node(ll to = 0, ll dist = 0) :to(to), dist(dist) {} }; bool vis[1010]; vector<node>vec[1010]; struct heapnode { ll u, d; heapnode(ll u = 0, ll d = 0) :u(u), d(d) {} bool operator<(const heapnode&a)const { return a.d < d; } }; void dij(int s) { priority_queue<heapnode>que; dis[s][s] = 0; que.push(heapnode(s, 0)); while (!que.empty()) { heapnode e = que.top(); que.pop(); int u = e.u; if (vis[u]) continue; vis[u] = 1; int len = vec[u].size(); for (int i = 0; i < len; i++) { node x = vec[u][i]; if (dis[s][x.to] > dis[s][u] + x.dist) { dis[s][x.to] = dis[s][u] + x.dist; que.push(heapnode(x.to, dis[s][x.to])); } } } } ll s[1010], u[1010], t[1010]; bool pj(ll x) { for (int i = 1; i <= k; i++) dp[i] = inf; ll arrivetime, watetime, settime; for (int i = 1; i <= k; i++) { settime = max(t[i], dp[i - 1] + dis[1][u[i - 1]]);//出发时间 第一层循环表示第i个和之后的一起,和之前的分开 arrivetime = settime + dis[1][u[i]];//到达时间 watetime = arrivetime - s[i];//等待时间 if (watetime > x) continue; dp[i] = min(dp[i], arrivetime); for (int j = i + 1; j <= k; j++) { if (settime >= t[j]) { arrivetime = arrivetime + dis[u[j - 1]][u[j]];//如果settime>t[j]就代表不需要等就可以之间带上它除法,所以到达时间就只要加上从j-1到j即可 watetime = max(arrivetime - s[j], watetime);//等待时间,如果到达时间减去s[j]>watetime,但是不可能就是这个,因为到第j-1个就等待了watetime的时间,所以这个只能更大 } else { arrivetime = arrivetime + dis[u[j - 1]][u[j]] + t[j] - settime; watetime = max(arrivetime - s[j], watetime + t[j] - settime); } //接下来就要更新settime if (watetime > x) break; settime = max(settime, t[j]); dp[j] = min(dp[j], arrivetime); } } if (dp[k] == inf) return false; return true; } int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { ll a, b, c; cin >> a >> b >> c; vec[a].push_back(node(b, c)); vec[b].push_back(node(a, c)); } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) dis[i][j] = inf; } for (int i = 1; i <= n; i++) { memset(vis, 0, sizeof(vis)); dij(i); } cin >> k; for (int i = 1; i <= k; i++) { cin >> s[i] >> u[i] >> t[i]; } dp[0] = 0, t[0] = 0, u[0] = 1; ll l = 0, r = 1e18; if (pj(0)) { cout << 0 << endl; return 0; } while (l < r) { ll mid = (l + r) / 2; if (pj(mid)) { r = mid; if (l + 1 == r) break; } else { l = mid; if (l + 1 == r) break; } } if (pj(l)) r = l; cout << r << endl; return 0; } /********************************************************************** Problem: 2252 User: echozhou Language: C++ Result: AC Time:732 ms Memory:10496 kb **********************************************************************/