USACO问题集
USACO问题集
USACO问题集
BRONZE PROBLEMS
*****************************************************************************
It's Halloween! Farmer John is taking the cows to a costume party, but
unfortunately he only has one costume. The costume fits precisely two cows
with a length of S (1 <= S <= 1,000,000). FJ has N cows (2 <= N <= 20,000)
conveniently numbered 1...N; cow i has length L i (1 <= Li <= 1,000,000). Two
cows can fit into the costume if the sum of their lengths is no greater than
the length of the costume. FJ wants to know how many pairs of two distinct
cows will fit into the costume.
INPUT FORMAT:
4 6
3
5
2
1
OUTPUT FORMAT:
OUTPUT DETAILS:
The four pairs are as follows: cow 1 and cow 3; cow 1 and cow 4; cow 2 and
cow 4; and finally cow 3 and cow 4.
We first sort the heights, using an efficient sort, which takes O(N log N)
time. Then, for each height k in the list, we wish to (efficiently) find the
index of the largest height that, when added to k, produces a sum less than H.
After we find this index, we can count the number of heights that, when added
to k, satisfy the given property. The simplest way to find this is with a
binary search, which is implemented in the solution below:
#include <algorithm>
#include <cstdio>
using namespace std;
int N, H, total;
int height [MAXN];
// finds the index of the first position whose height is <= value
inline int binsearch (int value)
{
int lo = 0, hi = N - 1, mid;
return lo;
}
int main ()
{
fscanf (fin, "%d %d", &N, &H);
total = 0;
return 0;
}
The cows are having their first election after overthrowing the tyrannical
Farmer John, and Bessie is one of N cows (1 <= N <= 50,000) running for
President. Before the election actually happens, however, Bessie wants to
determine who has the best chance of winning.
The election consists of two rounds. In the first round, the K cows (1 <= K <=
N) cows with the most votes advance to the second round. In the second round,
the cow with the most votes becomes President.
Given that cow i expects to get A i votes (1 <= Ai <= 1,000,000,000) in the
first round and Bi votes (1 <= Bi <= 1,000,000,000) in the second round (if he
or she makes it), determine which cow is expected to win the election. Happily
for you, no vote count appears twice in the A i list; likewise, no vote count
appears twice in the Bi list.
INPUT FORMAT:
* Line 1: Two space-separated integers: N and K
5 3
3 10
9 2
5 6
8 4
6 5
INPUT DETAILS:
There are 5 cows, 3 of which will advance to the second round. The cows expect
to get 3, 9, 5, 8, and 6 votes, respectively, in the first round and 10, 2, 6,
4, and 5 votes, respectively, in the second.
OUTPUT FORMAT:
* Line 1: The index of the cow that is expected to win the election.
OUTPUT DETAILS:
Cows 2, 4, and 5 advance to the second round; cow 5 gets 5 votes in the
second round, winning the election.
Problem where the goal is simply to follow the rules of the task description.
This one is slightly complex owing to the requirement for a 'sort' routine. C
and C++ programmers have easily used built-in sort routines (e.g., qsort).
Furthermore, the sort routine has to be able to sort one number while carrying
two other numbers in the exchanges. The program below is a simple
demonstration of how qsort can be used to perform such operations. Java and
Pascal programmers had merely to augment their variable-swap routines to swap
three variables. Some folks wrote two separate but similar sort routines; some
used an if statement to differentiate variable for testing.
Complete credit relied on an O(N logN) solution; O(N2) sorts were not fast
enough to get full points.
#include <stdio.h>
#include <stdlib.h>
struct vote_f {
int a;
int b;
int cownum;
} votes[50000];
comparea (struct vote_f *a, struct vote_f *b) { return b->a - a->a; }
compareb (struct vote_f *a, struct vote_f *b) { return b->b - a->b; }
main() {
FILE *fin = fopen ("elect.in", "r");
FILE *fout = fopen ("elect.out", "w");
int n, k, i;
Fatigued by the endless toils of farming, Farmer John has decided to try his
hand in the MP3 player market with the new iCow. It is an MP3 player that
stores N songs (1 <= N <= 1,000) indexed 1 through N that plays songs in a
"shuffled" order, as determined by Farmer John's own algorithm:
* After being played, a song's rating is set to zero, and its rating
points are distributed evenly among the other N-1 songs.
This process is repeated with the new ratings after the next song is played.
Determine the first T songs (1 <= T <= 1000) that are played by the iCow.
INPUT FORMAT:
3 4
10
8
11
INPUT DETAILS:
The iCow contains 3 songs, with ratings 10, 8, and 11, respectively. You must
determine the first 4 songs to be played.
OUTPUT FORMAT:
* Lines 1..T: Line i contains a single integer that is the i-th song
that the iCow plays.
3
1
2
3
OUTPUT DETAILS:
The program below is commented to show how each step is performed. The only
potentially tricky part is the use of two variables for the distribution: one
to count how many pieces get distributed and the second to say where they go.
The second variable is the trick for implementing the "Don't redistribute back
to the currently playing song" rule.
#include <stdio.h>
#include <stdlib.h>
void main() {
int bestrate, bestj, i, j, k, n, t, r[1000+1];
int evenlydistribute, leftover;
FILE *fin = fopen ("icow.in", "r");
FILE *fout = fopen ("icow.out", "w");
SILVER PROBLEMS
**********************************************************************
Farmer John is trying to rank the cows by skill level. Given a list the
results of M (1 <= M <= 4,500) two-cow rounds, determine the number of cows
whose ranks can be precisely determined from the results. It is guaranteed
that the results of the rounds will not be contradictory.
INPUT FORMAT:
5 5
4 3
4 2
3 2
1 2
2 5
OUTPUT FORMAT:
can be determined
OUTPUT DETAILS:
Cow 2 loses to cows 1, 3, and 4. Thus, cow 2 is no better than any of the cows
1, 3, and 4. Cow 5 loses to cow 2, so cow 2 is better than cow 5. Thus, cow 2
must be fourth, and cow 5 must be fifth. The ranks of the other cows cannot be
determined.
First, note that the problem can be converted into a graph, with the cows as
the nodes, and the games as the edges. (In particular, note that the graph is
a directed acyclic graph, or a DAG.)
For a certain cow X, X's rank can be determined if and only if the following
property is true: for every other cow Y, either cow X must be better than cow
Y, or cow Y must be better than cow X.
Thus, we can find which pairs of vertices in the graph are connected either by
doing a BFS for O(NM) overall or Floyd-Warshall for O(N 3) overall. Then, for
each cow, we check if every other cow is connected to it, and if so, we
increment our answer by 1.
#include <cstdio>
using namespace std;
FILE *fout = fopen ("contest.out", "w");
FILE *fin = fopen ("contest.in", "r");
int N, M, total = 0;
bool reach [MAXN][MAXN];
void main ()
{
fscanf (fin, "%d %d", &N, &M);
// read input
int a, b;
for (int i = 0; i < M; i++)
{
fscanf (fin, "%d %d", &a, &b);
a--, b--;
// we can find the rank of a cow if all other cows are connected to it
for (int j = 0; j < N; j++)
if (!reach [i][j] && !reach [j][i])
{
good = false;
break;
}
if (good)
total++;
}
The cows are trying to become better athletes, so Bessie is running on a track
for exactly N (1 <= N <= 10,000) minutes. During each minute, she can choose
to either run or rest for the whole minute.
The ultimate distance Bessie runs, though, depends on her 'exhaustion factor',
which starts at 0. When she chooses to run in minute i, she will run exactly a
distance of Di (1 <= Di <= 1,000) and her exhaustion factor will increase by 1
-- but must never be allowed to exceed M (1 <= M <= 500). If she chooses to
rest, her exhaustion factor will decrease by 1 for each minute she rests. She
cannot commence running again until her exhaustion factor reaches 0. At that
point, she can choose to run or rest.
At the end of the N minute workout, Bessie's exaustion factor must be exactly
0, or she will not have enough energy left for the rest of the day.
INPUT FORMAT:
5 2
10
OUTPUT FORMAT:
* Line 1: A single integer representing the largest distance Bessie can run
while satisfying the conditions.
OUTPUT DETAILS:
Bessie runs during the first minute (distance=5), rests during the second
minute, runs for the third (distance=4), and rests for the fourth and fifth.
Note that Bessie cannot run on the fifth minute because she would not end with
a rest factor of 0.
-First, try to not run during the minute, and see if this produces an
improvement. (Thus, check if the best value for i is better than the one for i
+ 1.)
-Then, for each number k from 1 to M, let Bessie run for exactly k minutes and
then rest for k minutes. See if this new value produces a greater value than
the best value for i + 2k (which is the number of minutes finished after
running for k minutes and resting for another k minutes).
Thus, since we do M updates for each of the N minutes, our total complexity is
O(NM). The following is a sample solution:
#include <cstdio>
using namespace std;
void main ()
{
fscanf (fin, "%d %d", &N, &M);
Farmer John wants to set up a telephone line at his farm. Unfortunately, the
phone company is uncooperative, so he needs to pay for some of the cables
required to connect his farm to the phone system.
There are N (1 <= N <= 1,000) forlorn telephone poles conveniently numbered
1...N that are scattered around Farmer John's property; no cables connect any
them. A total of P (1 <= P <= 10,000) pairs of poles can be connected by a
cable; the rest are too far apart.
The ith cable can connect the two distinct poles A i and Bi, with length Li (1
<= L_i <= 1,000,000) units if used. The input data set never names any {A i,Bi}
pair more than once. Pole 1 is already connected to the phone system, and pole
N is at the farm. Poles 1 and N need to be connected by a path of cables; the
rest of the poles might be used or might not be used.
As it turns out, the phone company is willing to provide Farmer John with K (0
<= K < N) lengths of cable for free. Beyond that he will have to pay a price
equal to the length of the longest remaining cable he requires (each pair of
poles is connected with a separate cable), or 0 if he does not need any
additional cables.
INPUT FORMAT:
* Line 1: Three space-separated integers: N, P, and K
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
INPUT DETAILS:
OUTPUT FORMAT:
* Line 1: A single integer, the minimum amount Farmer John can pay. If it is
impossible to connect the farm to the phone company, print -1.
OUTPUT DETAILS:
We construct the following graph G: each pole is a vertex, and each possible
connection between poles is an edge between corresponding vertices with weight
equal to the distance between the poles.
Now imagine we have a function f(lim) that tells us if there exists a path
from vertex 1 to vertex N using no more than K edges whose weights are greater
than lim. If we have such a function f, we can perform a binary search for the
answer: the smallest lim that works (in other words, the smallest k such that
f(k) is true) is the minimum amount Farmer John must pay.
In the worst case, we will need to evaluate function f O(log V) times (because
of the binary search), so the total running time of the entire algorithm is
O(E log2 V). (It's actually possible to compute the shortest path between two
vertices in a graph where all edges have weight 0 or 1 in linear time, but
that's not needed here.)
#include<fstream>
#include<vector>
GOLD PROBLEMS
*****************************************************************************
The cows, who always have an inferiority complex about their intelligence,
have a new guessing game to sharpen their brains.
A designated 'Hay Cow' hides behind the barn and creates N (1 <= N <=
1,000,000) uniquely-sized stacks (conveniently numbered 1..N) of hay bales,
each with 1..1,000,000,000 bales of hay.
The other cows then ask the Hay Cow a series of Q (1 <= Q <= 25,000) questions
about the the stacks, all having the same form:
What is the smallest number of bales of any stack in the range of stack
numbers Ql..Qh (1 <= Ql <= N; Ql <= Qh <= N)?
The Hay Cow answers each of these queries with a single integer A whose
truthfulness is not guaranteed.
Help the other cows determine if the answers given by the Hay Cow are self-
consistent or if certain answers contradict others.
INPUT FORMAT:
20 4
1 10 7
5 19 7
3 12 8
11 15 12
INPUT DETAILS:
The minimum number of bales in stacks 1..10 is 7, the minimum number of bales
in stacks 5..19 is 7, the minimum number of bales in stacks 3..12 is 8, and
the minimum number of bales in stacks 11..15 is 12.
OUTPUT FORMAT:
print the index from 1..Q of the earliest query whose answer
OUTPUT DETAILS:
Query 3 ("3 12 8") is the first that is inconsistent with those before it.
From queries 1 and 2 and the fact that all hay stacks have a distinct number
of bales, we deduce that one of stacks 5..10 must contain exactly 7 bales.
However, this stack contradicts the answer to query 3.
The first (and most crucial) observation to make is that if there exists a
list of stack sizes that satisfies queries 1...m, then the same set satisfies
queries 1...m-1. So we can perform binary search on the biggest sequence of
queries that can be satisfied, and reduce the problem to finding whether a set
of queries is satisfiable.
Then, given a sequence of query results, we can find out what's the lowest
number of bales in each stack in O(N+Q logQ) time by sweeping through the
queries and tracking the 'limiting query' using a heap. This can alternatively
be done using a range tree, although that's a bit slower.
We then need to check that minimum values are indeed present in the ranges.
For all the queries whose answer is x, the value x must be present in their
intersection since x can only appear once total. Then x must appear once as
one of the 'minimum' values since x is also an upper bound on that region as
well. So this can be checked in O(N) time using a lookup list as well. Note
that this condition is sufficient since all the other duplicated values (in
the lower bound list) can have their values rised to arbitrary values without
causing any further problems.
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
struct qtype {
int p1, p2, res, id;
bool operator < (const qtype & o)const { return p1 < o.p1; }
}lis[MAXQ];
needt = 0;
last[v[i]] = i;
return 1;
}
void main ()
{
int i, j, tot, ans, del;
freopen ("bales.in", "r", stdin);
freopen ("bales.out", "w", stdout);
scanf ("%d%d", &n, &q);
The oppressively hot summer days have raised the cows' clamoring to its
highest level. Farmer John has finally decided to build an artificial lake.
For his engineering studies, he is modeling the lake as a two-dimensional
landscape consisting of a contiguous sequence of N soon-to-be-submerged levels
(1 <= N <= 100,000) conveniently numbered 1..N from left to right.
Each level i is described by two integers, its width W_i (1 <= W i <= 1,000)
and height (like a relative elevation) Hi (1 <= Hi <= 1,000,000). The heights
of FJ's levels are unique. An infinitely tall barrier encloses the lake's
model on the left and right. One example lake profile is shown below.
* * :
* * :
* * 8
* *** * 7
* *** * 6
* *** * 5
* ********** 3
*************** 2
*************** 1
Level | 1 |2| 3 |
In FJ's model, he starts filling his lake at sunrise by flowing water into the
bottom of the lowest elevation at a rate of 1 square unit of water per minute.
The water falls directly downward until it hits something, and then it flows
and spreads as room-temperature water always does. As in all good models,
assume that falling and flowing happen instantly. Determine the time at which
each elevation's becomes submerged by a single unit of water.
| |
* | * * | * * *
* V * * V * * *
* * * .... * *~~~~~~~~~~~~*
* ** * *~~~~** : * *~~~~**~~~~~~*
* ** * *~~~~** : * *~~~~**~~~~~~*
* ** * *~~~~**~~~~~~* *~~~~**~~~~~~*
INPUT FORMAT:
integers: Wi and Hi
4 2
2 7
6 4
INPUT DETAILS:
Three levels just as in the example above. Water will fill the first level
because it is the lowest.
OUTPUT FORMAT:
of height 1.
50
26
We try to solve the problem for each level separately. For each level, the
amount of water required until it overflows can be broken down into three
parts. WOLOG, we assume the level is to the left of the level of minimum
height. The three parts are:
To the left of the level. Water will flow this way unti it encounters
the first level that has a higher height. So, for each level, we need to
find the first level to its left that has a higher height. This can be
done using a stack in O(n) time.
Between the level and the lowest level. The water levels forms a series
of 'steps', which can be tracked in a stack if we consider the levels
from right to left. This can also be calculated in O(n) time.
To the right of the lowest level. If we consider the levels one by one
leftwards starting from the one to the left of the lowest level, the
water level at the lowest level can only increase. So it suffices to
keep a pointer to how far to the right gets submerged and increase this
counter as we go. This clearly also runs in O(n)
Combining these three parts, we get an O(n) algorithm. Many of the solutions
submitted by contestants used much cleverer algorithms that combines these
three steps into a single one, but most are still based on this 'step' idea.
Here is Neal Wu's explanation on how he did this problem:
Add in the two infinite barriers as 'levels' with infinite height for
simplicity. We will find the answer for each level in the order they are
filled, keeping track of the current time when calculating each.
Note that after we have filled level L, the water will go in the direction of
the shorter neighbor level of L. For example, in the following diagram, after
level 2 is filled, the water will flow to the right:
* * 8
* * 7
**** * 6
**** ** * 5 <-- heights
**** **** * 4
**** ******* * 3
**** ********* 2
*************** 1
1 2 3 4 5 6
Levels
The water will keep flowing to the right (and thus 'skipping' levels) until an
increase in height occurs. Thus, in the example above, level 6 will be filled
next after level 2 is finished.
Also, note that at this point both level 2 and level 3 share the same water
level. They will always remain at the same height since the water fills them
evenly. Thus, we can 'merge' level 2 into level 3 (the new width of level 3
will be the sum of its original width and the width of level 2), and delete
level 2. Note that to implement this merging efficiently we can use a linked
list of levels (which enables constant time deletion of a level).
This gives us a fairly simple algorithm: find the level which the water
currently fills (starting with the shortest level), and calculate the time at
which it becomes submerged (which is equal to the time when the level began to
fill up added to the width of the level). Next, find how long it takes for the
level to fill up to the height of the shorter of its two neighbors, and add
this to our current time. Finally, continue in the direction of the shorter
neighbor until we reach an increase in level heights. This level is the next
level to fill with water.
At first, it seems this approach is O(N 2), since we can skip up to O(N) levels
each time. However, the algorithm is actually linear time because of the
following fact: after we skip a level, we cannot skip it again. This is
because after a level is skipped, the water must come back to it from the
opposite direction, which means it must fill the level. (In the above example,
the water will skip level 5, fill level 6, and then come back to level 5 and
fill it.) Therefore each level can be skipped at most once, so the algorithm
takes O(N) time overall. The following is a sample implementation:
#include <cstdio>
using namespace std;
void main () {
fscanf (fin, "%d", &N);
height [0] = height [N + 1] = INF; // infinite walls
while (ind <= N && height [next [ind]] < height [ind])
ind = next [ind];
}
}
Farmer John has decided to give each of his cows a cell phone in hopes to
encourage their social interaction. This, however, requires him to set up cell
phone towers on his N (1 <= N <= 10,000) pastures (conveniently numbered 1..N)
so they can all communicate.
Exactly N-1 pairs of pastures are adjacent, and for any two pastures A and B
(1 <= A <= N; 1 <= B <= N; A != B) there is a sequence of adjacent pastures
such that A is the first pasture in the sequence and B is the last. Farmer
John can only place cell phone towers in the pastures, and each tower has
enough range to provide service to the pasture it is on and all pastures
adjacent to the pasture with the cell tower.
Help him determine the minimum number of towers he must install to provide
cell phone service to each pasture.
INPUT FORMAT:
* Lines 2..N: Each line specifies a pair of adjacent pastures with two space-
separated integers: A and B
1 3
5 2
4 3
3 5
INPUT DETAILS:
Farmer John has 5 pastures: pastures 1 and 3 are adjacent, as are pastures 5
and 2, pastures 4 and 3, and pastures 3 and 5. Geometrically, the farm looks
like this (or some similar configuration)
4 2
| |
1--3--5
OUTPUT FORMAT:
install
OUTPUT DETAILS:
The vertices left in S form a minimum dominating set. For a proof of why this
works, see http://www.cs.clemson.edu/~bcdean/greedy_tree_dom.swf.
Note that the running time of this algorithm is very good, O(N), since each
vertex is visited once in the postorder traversal and each vertex is added to
S at most once. Checking whether a vertex can be removed can also be done
efficiently by keeping track of how many vertices in S it is adjacent to. An
implementation of this algorithm is shown below.
#include <stdio.h>
#include <iostream>
#include <vector>
void traverse(int v)
{
for(int i=0; i<E[v].size(); i++)
if(p[v] != E[v][i])
{
p[E[v][i]] = v;
traverse(E[v][i]);
}
if(c[v] == 0)
{
B.push_back(v);
c[v]++;
for(int i=0; i<E[v].size(); i++)
{
c[E[v][i]] += 2; B.push_back(E[v][i]);
void main()
{
FILE* in = fopen("tower.in", "r");
FILE* out = fopen("tower.out", "w");
int u, v;
traverse(0);
int numRemove = 0;
for(int i=B.size()-1; i>=0; i--)
{
bool canRemove = (c[B[i]] > 1);
if(canRemove)
{
c[B[i]]--;
for(int j=0; j<E[B[i]].size(); j++)
c[E[B[i]][j]]--;
}
numRemove += canRemove;
}
GOLD PROBLEMS
*****************************************************************************
The N (1 <= N <= 50,000) cows, conveniently numbered 1..N, are trying to learn
some encryption algorithms. After studying a few examples, they have decided
to make one of their own! However, they are not very experienced at this, so
their algorithm is very simple:
Each cow i is given a starting number C i (0 <= Ci < 90,000,000), and then all
the cows perform the following process in parallel:
* First, each cow finds the sum of the numbers of the other N-1
cows.
* After all cows are finished, each cow replaces her number
with the sum she computed. To avoid very large numbers, the
They told Canmuu the moose about it in November; he was quite impressed.
Then one foggy Christmas Eve, Canmuu came to say: "Your algorithm is too easy
to break! You should repeat it T (1 <= T <= 1,414,213,562) times instead."
Obviously, the cows were very frustrated with having to perform so many
repetitions of the same boring algorithm, so after many hours of arguing,
Canmuu and the cows reached a compromise: You are to calculate the numbers
after the encryption is performed!
*Some extra feedback will be provided for the first 10 submissions to this
problem.
INPUT FORMAT:
3 4
INPUT DETAILS:
OUTPUT FORMAT:
* Lines 1..N: Line i contains a single integer representing the number of cow
i (modulo 98,765,431) at the end of the encryption.
SAMPLE OUTPUT (file sumsums.out):
26
25
29
OUTPUT DETAILS:
Cows' numbers
0 1 0 4
1 4 5 1
2 6 5 9
3 14 15 11
4 26 25 29
Let S be the sum of all the numbers at the beginning. We can construct a table
of the value of each cow's numbers after each turn:
0 Ci S
1 S - Ci (n - 1) * S
2 (n - 2) * S + Ci (n - 1)2 * S
3 (n2 - 3n + 3) * S + Ci (n - 1)3 * S
In particular, note that the coefficient of S in cow i's number on the t-th
turn is (n - 1)t - 1 - (n - 1)t - 2 + (n - 1)t - 3 - ... ± (n - 1)1 ∓ (n - 1)0, and
the coefficient of Ci is (-1)t. (Both of these statements can be proven by
induction.)
Now, all we need to do to solve the problem is evaluate this sum (modulo
98,765,431). However, the sum can have 1 billion terms, so we need to find an
efficient way of doing this. Two possible methods, that can both be
implemented in O(log t), are described below:
The second method is to find the sum using matrix powering. We note that on
each turn, the coefficient of S in each cow's number is multiplied by (n - 1),
and then 1 is either added to the coefficient or subtracted from it, depending
on whether t is even or odd. In order to simulate this using matrix powering,
we would like to create a 2-element vector V and a 2 x 2 matrix M such that V
[0] is the coefficient of S, and V [1] is either 1 or -1. Multiplying V by the
matrix M once should simulate one turn. In particular, we want to multiply V
[0] by n - 1, and then add V [1] to it, and we want to 'flip' V [1] between 1
and -1 each time. Thus, M should be the following matrix:
| n - 1 0 |
| |
| 1 -1 |
Two solutions are presented corresponding to the two methods given above. The
following is a power of two summation solution from Neal Wu:
#include <cstdio>
using namespace std;
return total;
}
Void main ()
{
fscanf (fin, "%d %d", &N, &T);
sum %= MOD;
#include <cstdio>
#include <cstring>
int res[2],v[2][2],tem[2][2],t,t1;
int lis[MAXN],dif[MAXN],n;
long long tot;
void main(){
int i;
freopen("sumsums.in","r",stdin);
freopen("sumsums.out","w",stdout);
scanf("%d%d",&n,&t);
for(i=tot=0,0;i<n;i++){
scanf("%d",&lis[i]);
dif[i]=lis[i]-lis[0];
tot+=dif[i];
}
memset(v,0,sizeof(v));
memset(res,0,sizeof(res));
res[0]=lis[0]%M;
res[1]=tot%M;
v[0][0]=(n-1)%M;
v[0][1]=1;
v[1][1]=-1;
for(t1=t;t1;t1/=2){
if(t1%2){
res[0]=((long long)res[0]*v[0][0]+(long long)res[1]*v[0][1])
%M;
res[1]=((long long)res[1]*v[1][1])%M;
}
mul(v,v);
memcpy(v,tem,sizeof(v));
}
for(i=0;i<n;i++)
printf("%d\n",((res[0]+((t%2==0)?(dif[i]):(-dif[i])))%M+M)%M);}
The 2*N (3 <= N <= 1,000) cows have assembled the Bovine Accordion and Banjo
Orchestra! They possess various levels of skill on their respective
instruments: accordionist i has an associated talent level A i (0 <= Ai <=
1,000); banjoist j has an associated talent level B j(0 <= Bj <= 1,000).
To make matters worse, when one or more of the musicians is skipped, they will
be greatly upset at their wasted talent and will engage in massive binge
drinking to wash away their sorrows.
After all pairings are made, a list is constructed of the groups of each of
the consecutive skipped musicians (of either instrument). Every group of one
or more consecutive skipped cows will gather together to consume kegs of ice
cold orange soda in an amount proportional to the square of the sum of their
wasted talent.
Specifically, FJ has calculated that if the x-th to y-th accordionists are
skipped, they will consume precisely (A x + Ax+1 + Ax+2 + ... + Ay)2 dollars worth
of orange soda in the process of drinking themselves into oblivion. An
identical relationship holds for the banjoists. FJ realizes that he'll end up
getting stuck with the bill for his cows' drinking, and thus takes this into
account when choosing which pairings to make.
Find the maximum amount of total profit that FJ can earn after the
contributions are collected and the orange soda is paid for.
INPUT FORMAT:
1
INPUT DETAILS:
talent levels (1, 1, 5), and the banjoists have talent levels (5, 1, 1).
OUTPUT FORMAT:
* Line 1: A single integer that represents the maximum amount of cash that FJ
can earn.
17
OUTPUT DETAILS:
- 8 = 17.
Since the pairings cannot intersect, this problem can be solved using DP with
the state being the last 'pair' of accordionist and banjoist (denoted A and B
from here on). This gives O(N2) states and O(N2) state transitions for each
state as there are O(N2) possible previous pairs, the state transition
function is:
Best(i,j)=max{i1<i,j1<j|Best(i1,j1)-SQR(sum(A_i1...A_(i-1)))-
SQR(sum(B_j1...B_(j-1)))}+A_i*B_j
Now we try to get down to O(N 2) by optimizing the state transition using
convexity. We first consider the case where no cows in A are skipped, or when
i1=i-1. So we need to find:
max{j1<j|Best(i-1,j)-SQR(sum(B_j1...B_(j-1))}+A_i*B_j
If we let SB denote the partial sum of the B array, then our transition
formula becomes:
max{j1<j|Best(i-1,j)-SQR(SB_(j-1)-SB(j1-1))}+A_i*B_j =max{j1<j|Best(i-1,j)-
SQR(SB_(j1-1))+2*SB_(j1-1)*SB_(j-1)}+A_i*B_j+SQR(SB_(j-1))
We can ignore the last two terms since they're constant depending only on i
and j. If we look at the first term, we're looking for the max of a linear
combination of two values depending on j1 where the ratio is dependent on j.
The case where nothing in B is skipped can be dealt with similarly. The only
catch is that should we process the states in incremental i and then
incremental j, we'll need to keep track of N+1 convex hulls, one for the
previous 'row' and one for each of the columns.
#include <cstdio>
#include <cstring>
int n;
double a[MAXN],b[MAXN],bes[MAXN][MAXN],ans;
double s1[MAXN],s2[MAXN];
double hull[MAXN][MAXN][2];
int hullt[MAXN],p[MAXN];
void main()
{
int i,j,i1,j1;
freopen("mkpairs.in","r",stdin);
freopen("mkpairs.out","w",stdout);
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%lf",&a[i]);
for(s1[0]=a[0],i=1;i<n;i++) s1[i]=s1[i-1]+a[i];
for(i=0;i<n;i++) scanf("%lf",&b[i]);
for(s2[0]=b[0],i=1;i<n;i++) s2[i]=s2[i-1]+b[i];
memset(bes,0,sizeof(bes));
for(i=1;i<n;i++)
initialize(i);
for(ans=i=0;i<n;i++){
initialize(0);
for(j=0;j<n;j++){
bes[i][j]=-((i==0)?0:sqr(s1[i-1]))-((j==0)?0:sqr(s2[j-1]));
if(i>0){
if(j>0){
bes[i][j]>?=query(0,2*s2[j-1])-sqr(s2[j-1]);
bes[i][j]>?=query(j,2*s1[i-1])-sqr(s1[i-1]);
}
hulladd(0,s2[j],bes[i-1][j]-sqr(s2[j]));
}
bes[i][j]+=a[i]*b[j];
ans>?=bes[i][j]-sqr(s1[n-1]-s1[i])-sqr(s2[n-1]-s2[j]);
}
for(j=0;j+1<n;j++){
hulladd(j+1,s1[i],bes[i][j]-sqr(s1[i]));
}
}
printf("%0.0lf\n",ans);
}
Canmuu and his friends have recently acquired a large cache of plutonium and
have agreed to bury their newfound treasure at some road intersection deep in
the Canadian wilderness. Any sort of treasure burial calls for a treasure map
so they've decided to create one of their own.
Ever the alert moose, Canmuu drew some trial maps to see what they would look
like depending on where the treasure was buried. Canmuu noticed that the moose
might draw similar maps even if they bury their treasure in two different
locations. Their curiosity piqued, the herd began trying to figure out how
many distinct maps they could end up making.
such that
By way of example, consider the maps below where N = 4; the treasure might be
buried at any of four intersections:
+ + X +
/| /| /| /|
\| \| \| \|
+ + + X
The final two maps, however, are not distinct since one can create a
correspondence for the vertices (consider the map upside down) and then the
roads correspond exactly. Thus, only three maps are distinct.
How many distinct maps are possible for a given set of roads?
*Some extra feedback will be provided for the first 10 submissions to this
problem.
INPUT FORMAT:
intersections A and B
1 2
2 3
3 1
1 4
INPUT DETAILS:
4---1---2
\ /
OUTPUT FORMAT:
maps
OUTPUT DETAILS:
To tackle this problem most effectively, we first establish that the road
network described in the problem is a cycle with trees 'coming off' it. So we
can root all the trees by the vertex they have on the cycle and denote nodes
by 'parent' and children'.
We essentially want to assign an 'id' to the graph surrounding each of the
vertices, which is a collection of several subtrees (its children) and a graph
that contains the cycle.
There are two ways of doing this, either by computing hash values for each
subgraph or by computing 'ids' as we proceed and only hash cyclic shifts of
the cycle. The first method is faster in practice and just accurate, but the
second is slightly easier to code due to usage of C++ STL.
Since a tree is a collection of its subtrees, we can assign 'id's to all the
subtrees rooted at each vertex by proceeding at the outermost layer and
proceed inwards.
Then we have to distinguish between all the cyclic shifts (with reflections)
of the cycles (which is how we could 'orient' the cycle with respect to the
tree the treasure is buried in). This can be accomplished by the standard
Rabin-Karp string hash, done once clockwise and once counter clockwise.
Then for each distinct tree, we can just count the trees that have distinct
ids by going down recursively, and when we're at a node, only count its
children that have distinct ids (so if two of its children have the same
subtree, only count one of them). This is correct since the 'root' is now a
special node (an orientation of the cycle).
This runs in O(N) time if hashing is used and O(NlogN) if set/map is used. The
test data were generated as follows:
Case 1: Sample.
Case 5: 10 trees with AAABBCCCBB pattern, N = 53, the trees are specially
designed that they cover almost every simple cases.
Case 13: Repeated AB pattern, changed one B into a special big tree.
#include <stdio.h>
#include <string.h>
#define maxn 100000
#define maxh 200003
#define maxH 1000000003LL
int lib[3], lp = 0;
int main () {
int i, a, b, c;
scanf("%d",&n);
p = 0;
memset(ind, -1, sizeof(ind));
for (i = 0; i < n; i ++) {
scanf("%d%d",&a,&b);
a --;
b --;
next[p] = ind[a];
to[p] = b;
ind[a] = p ++;
next[p] = ind[b];
to[p] = a;
ind[b] = p ++;
}
memset(used, 0, sizeof(used));
for (i = 0; i < sp; i ++)
used[stack[i]] = 1;
/*
for (i = 0; i < sp; i ++)
printf("%d\n",stack[i]);
fflush(stdout);
*/
h2[0] = 0;
for (i = 1; i < sp; i ++)
h2[0] = (h2[0] * 147804523 + stack[i]) % maxH;
h2[0] = (h2[0] * 147804523 + stack[0]) % maxH;
for (i = 1; i < sp; i ++)
h2[i] = (h2[i - 1] * 147804523 % maxH + stack[i] + maxH - big *
stack[i] % maxH) % maxH;
b = 0;
c = 0;
for (i = 0; i < sp; i ++) {
if (h1[i] == h2[i]) {
b |= 1;
c = i;
}
if (h1[i] == h2[(i + 1) % sp] && !(b&1)) {
b |= 2;
c = (i + 1) % sp;
}
}
if (b & 1)
a = a / 2 + 1;
else
if (b & 2)
a = a / 2;
int ans = 0;
printf("%d\n", ans);
BRONZE PROBLEMS
*****************************************************************************
Bookshelf [Neal Wu, 2007]
Farmer John recently bought a bookshelf for cow library, but the shelf is
getting filled up quite quickly, and now the only available space is at the
top.
Each of the N cows (1 <= N <= 20,000) has some height of H i (1 <= Hi <=
10,000) and a total height summed across all N cows of S. The bookshelf has a
height of B (1 <= B <= S < 2,000,000,007).
To reach the top of the bookshelf taller than the tallest cow, one or more of
the cows can stand on top of each other in a stack, so that their total height
is the sum of each of their individual heights. This total height must be no
less than the height of the bookshelf. Since more cows than necessary in the
stack can be dangerous, your job is to find the set of cows that produces a
stack of the smallest number of cows possible such that the stack can reach
the bookshelf.
INPUT FORMAT:
6 40
18
11
13
19
11
INPUT DETAILS:
Six cows; bookshelf height 40. Cow heights fall in the range 6..19.
OUTPUT FORMAT:
* Line 1: A single integer representing the size of the smallest set of cows
that can reach the bookshelf.
OUTPUT DETAILS:
#include <cstdio>
#include <algorithm>
using namespace std;
int N, B;
int heights [MAXN];
int solve () {
int sum = 0;
void main () {
fscanf (fin, "%d %d", &N, &B);
for (int i = 0; i < N; i++)
fscanf (fin, "%d", heights + i);
FJ has N cows (1 <= N <= 20) each with some height of H i (1 <= Hi <= 1,000,000
- these are very tall cows). The bookshelf has a height of B (1 <= B <= S,
where S is the sum of the heights of all cows).
To reach the top of the bookshelf, one or more of the cows can stand on top of
each other in a stack, so that their total height is the sum of each of their
individual heights. This total height must be no less than the height of the
bookshelf in order for the cows to reach the top.
Since a taller stack of cows than necessary can be dangerous, your job is to
find the set of cows that produces a stack of the smallest height possible
such that the stack can reach the bookshelf. Your program should print the
minimal 'excess' height between the optimal stack of cows and the bookshelf.
INPUT FORMAT:
5 16
5
6
OUTPUT FORMAT:
OUTPUT DETAILS:
To solve this problem, we simply need to look at the sums of all 2 N subsets of
the numbers. (This is possible since N <= 20, and so there are at most around
one million such subsets.) There are several methods of doing this, but two
fairly simple methods are the following:
The second method is to use recursion to generate every sum. For each cow, we
have two possibilities: we either use the cow or we don't. This gives us a
fairly simple solution that is O(2N) with a medium overhead of function calls.
#include <cstdio>
using namespace std;
FILE *fout = fopen ("shelf2.out", "w");
FILE *fin = fopen ("shelf2.in", "r");
int N, B;
int heights [MAXN];
int sum, best = INF;
void main () {
fscanf (fin, "%d %d", &N, &B);
#include <cstdio>
using namespace std;
int N, B;
int heights [MAXN];
int best = INF;
// either we are finished or our current sum is worse than the best so far
if (num == N || sum >= best)
return;
void main ()
{
fscanf (fin, "%d %d", &N, &B);
for (int i = 0; i < N; i++)
fscanf (fin, "%d", heights + i);
solve (0, 0);
fprintf (fout, "%d\n", best - B);
}
Bessie is playing a card game with her N-1 (2 <= N <= 100) cow friends using a
deck with K (N <= K <= 100,000; K is a multiple of N) cards. The deck
contains M = K/N "good" cards and K-M "bad" cards. Bessie is the dealer and,
naturally, wants to deal herself all of the "good" cards. She loves winning.
Her friends suspect that she will cheat, though, so they devise a dealing
system in an attempt to prevent Bessie from cheating. They tell her to deal as
follows:
1. Start by dealing the card on the top of the deck to the cow
to her right
2. Every time she deals a card, she must place the next P (1 <=
in a counterclockwise manner
Bessie, desperate to win, asks you to help her figure out where she should put
the "good" cards so that she gets all of them. Notationally, the top card is
card #1, next card is #2, and so on.
INPUT FORMAT:
3 9 2
INPUT DETAILS:
Bessie is playing cards with two cow friends and a deck of 9 cards. She must
place two cards on the bottom of the deck each time she deals one.
OUTPUT FORMAT:
should place "good" cards, such that when dealt, Bessie will
OUTPUT DETAILS:
Bessie should put the "good" cards in positions 3, 7, and 8. The cards will be
dealt as follows; the card numbers are "position in original deck":
Initial configuration 1 2 3 4 5 6 7 8 9 - - - - - - - - -
Bessie will end up with the "good cards" that have been placed in
The simplest brute force approach is simple until it comes time to "put the
top card on the bottom". One can implement this in a few ways:
save the top card, move all the cards 'up' one slot in an array, set the
bottom card to the saved top card
a linked list: remove the head element and place it on the end
an oversized array that is large enough to accommodate a large number of
cards-moved-to-bottom; keep an index of the 'decktop' and 'deckbottom'.
Moving a card to the bottom just increments decktop and deckbottom while
copying the first card to the bottom.
My solution (below) uses the third method since it's pretty darn simple to
implement:
#include <stdio.h>
int cmp (int *a, int *b) { return *a - *b; }
main () {
FILE *fin = fopen ("cheat.in", "r");
FILE *fout = fopen ("cheat.out", "w");
int n, k, p, i, j;
int deck[100000 * 11], decktop, deckbottom, betsy[100000], nbetsy;
int player;
fscanf (fin, "%d %d %d", &n, &k, &p);
SILVER PROBLEMS
*****************************************************************************
Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of
course, she'd like to fill it with the best charms possible from the N (1 <= N
<= 3,402) available charms. Each charm i in the supplied list has a weight W i
(1 <= Wi <= 400), a 'desirability' factor D i (1 <= Di <= 100), and can be used
at most once. Bessie can only support a charm bracelet whose weight is no
more than M (1 <= M <= 12,880).
Given that weight limit as a constraint and a list of the charms with their
weights and desirability rating, deduce the maximum possible sum of ratings.
INPUT FORMAT:
* Lines 2...N+1: Line i+1 describes charm i with two space-separated integers:
Wi and Di
4 6
1 4
2 6
3 12
2 7
INPUT DETAILS:
OUTPUT FORMAT:
23
OUTPUT DETAILS:
Without the second possible charm, the 4+12+7=23 is the highest value for
weight 1+2+3 <= 6
This is one of the classic "knapsack" problems: 'Items' with a 'value' and
'size' can be stuffed an integer number of times into a container of some
limited size with the goal of maximizing the value of the items inserted.
The classic solution pivots on a list of the best possible value that can be
obtained for the set of items so far seen. The array's subscript is 'size';
it's value is "the best value that can be obtained for the items so far
processed.
Initially, of course, the array's values are all zero. Adding the first
element is easy: bestvalue[itemweight] = itemvalue.
Subsequent items are processed one-by-one as follows. The item's weight and
value are (experimentally) added to each of the *existing* weight/value pairs
in the bestvalue array (including the 0/0 element). If the new weight/value
pair is better, it replaces the old weight value.
By way of example, consider the four items from the problem description:
1 4
2 6
3 12
2 7
The maximum allowed weight is 6, so 6+1 elements are needed in the 'bestvalue'
array:
0 0 0 0 0 0 0 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
The first element (weight 1, value 4) is easy to insert:
0 4 0 0 0 0 0 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
The second element (weight 2, value 6) requires two additions. For purposes of
explanation, we will first add it to the 0/0 element:
V-------V
0 4 *6* 0 0 0 0 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
and then to the weight=1 element, which currently has value 4:
V-------V
0 4 6 *10* 0 0 0 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
Important point:It is now clear that we can run into trouble if, for instance,
our weight was 1. In that case, we'd be modifying sequential elements --
elements whose new value should be based on the original 'best' matrix value
and not the newly increased values. Thus, we must either make a new (properly
copied) best matrix so modifications are made properly OR we must modify the
'best' matrix from the larger elements to smaller
The third element (weight 3, value 12) requires four additions (to weights 0,
1, 2, and 3). We will start at weight 3 and proceed 'backwards':
V-----------V
0 4 6 10 0 0 *22* <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
V-----------V
0 4 6 10 0 *12* 22 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
V-----------V
0 4 6 10 *16* 12 22 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
In the final case, we will overwrite a now inferior 'best value' element:
V-----------V
0 4 6 *12* 16 12 22 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
The fourth and final element (weight 2, value 7) will require potential
augmentation of all 7 of the best values since all slots are now occupied.
Working backwards:
V-------V
0 4 6 12 16 12 22 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
No modifications since the aggregate weight is too large. Likewise:
V-------V
0 4 6 12 16 12 22 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
Regular calculations and potential modifications then commence. The 6th item
is overwritten since 16+7 > 22 (and so on):
V-------V
0 4 6 12 16 12 *23* <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
V-------V
0 4 6 12 16 *19* 23 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
For weight 2 + 2, the new value 6+7=13 is less than the current best value of
16, so no modification occurs:
V-------V
0 4 6 12 16 19 23 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
Likewise for weight 1 + 2 no modificastion occurs since 4+7=11 < 12:
V-------V
0 4 6 12 16 19 23 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
The final weight 0+2 has a new best value:
V-------V
0 4 *7* 12 16 19 23 <-- best value
0 1 2 3 4 5 6 <-- for this weight (subscript)
Having now processed all the input, the 'best value' array is complete. In
this case element bestvalue[6]=23 is the largest of all the values. One can
well imagine this would not be the case if, e.g., an item with weight 5 and
value 1,000 existed. That might make the largest value appear in some slot
other than the final one (i.e., if the other weights were all > 1). Thus we
scan the best value array to find the largest element, which is the highest
possible value that can be created within the size/weight constraints.
I coded this task using two arrays and inefficient copy operators:
#include <stdio.h>
main () {
FILE *fin = fopen ("charm.in", "r");
FILE *fout = fopen ("charm.out", "w");
int n, m, w, d, i, j, biggest;
Richard Peng, who has coded tasks like this many times, has evolved a more
sophisticated solution that requires but one array (processed in reverse
order) and uses the cool '>?=' operator for replacing 'improved' elements.
Note that his loops are generally 'correct by construction' -- no need to
check for out-of-bounds indices since the loops are properly constrained. Of
course his solution is also just about as fast as we know how to solve a task
like this:
#include <cstdio>
#include <cstring>
int bes[12880], n, m, a, b, i, j;
int main () {
freopen ("charm.in", "r", stdin);
freopen ("charm.out", "w", stdout);
scanf ("%d%d", &n, &m);
memset (bes, 0, sizeof (bes));
for (i=0; i<n; i++){
scanf ("%d%d", &a, &b);
for (j=m; j>=a; j--)
bes[j]>?=bes[j-a]+b;
}
printf ("%d\n", bes[m]);
return 0;
}
Farmer John had just acquired several new farms! He wants to connect the farms
with roads so that he can travel from any farm to any other farm via a
sequence of roads; roads already connect some of the farms.
4 1
1 1
3 1
2 3
4 3
1 4
INPUT DETAILS:
Four farms at locations (1,1), (3,1), (2,3), and (4,3). Farms 1 and 4 are
connected by a road.
OUTPUT FORMAT:
OUTPUT DETAILS:
Connect farms 1 and 2 with a road that is 2.00 units long, then connect farms
3 and 4 with a road that is 2.00 units long. This is the best we can do, and
gives us a total of 4.00 unit lengths.
We note that since all edges have non-negative weights, there will not be a
cycle in the final version of the graph. Thus, this problem is equivalent to
finding the minimum spanning tree in a graph where the edge weights are the
Euclidean distances (with the exception of a few whose distances are set to
zero).
Several minimum spanning tree algorithms can be use here. Since we're finding
the MST of a dense graph, the best option is probably the O(n^2) version of
the Prim algorithm:
By the way: This problem can actually be done in O(nlogn+m) time. The idea is
basically the edges that could potentially be in the minimum spanning tree
must belong to what's known as the Delaunay triangulation, which has O(n)
edges. We can find the Delaunary triangulation in O(nlogn) time and apply a
fast version of Kruskal's algorithm for sparse graphs to get the desired
runtime.
Below is Chinese sophomore ShiMen Xu's compact solution (which might or might
not match the description above):
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
int us [1010];
double ans;
int main () {
FILE *f = fopen ("roads.out", "w");
init ();
work ();
fprintf (f, "%0.2lf\n", ans);
return 0;
}
void init () {
fin >> N >> M;
for (int i = 1; i <= N; i++)
fin >> p[i].x >> p[i].y;
void work () {
int root, cnt[1010], id;
Farmer John is leaving his house promptly at 6 AM for his daily milking of
Bessie. However, the previous evening saw a heavy rain, and the fields are
quite muddy. FJ starts at the point (0, 0) in the coordinate plane and heads
toward Bessie who is located at (X, Y) (-500 <= X <= 500; -500 <= Y <= 500).
He can see all N (1 <= N <= 10,000) puddles of mud, located at points (A_i,
B_i) (-500 <= A_i <= 500; -500 <= B_i <= 500) on the field. Each puddle
occupies only the point it is on.
Having just bought new boots, Farmer John absolutely does not want to dirty
them by stepping in a puddle, but he also wants to get to Bessie as quickly as
possible. He's already late because he had to count all the puddles. If Farmer
John can only travel parallel to the axes and turn at points with integer
coordinates, what is the shortest distance he must travel to reach Bessie and
keep his boots clean? There will always be a path without mud that Farmer John
can take to reach Bessie.
INPUT FORMAT:
1 2 7
0 2
-1 3
3 1
1 1
4 2
-1 1
2 2
INPUT DETAILS:
Bessie is at (1, 2). Farmer John sees 7 mud puddles, located at (0, 2); (-1,
3); (3, 1); (1, 1); (4, 2); (-1, 1) and (2, 2). Pictorially:
4 . . . . . . . .
3 . M . . . . . .
Y 2 . . M B M . M .
1 . M . M . M . .
0 . . * . . . . .
-1 . . . . . . . .
-2-1 0 1 2 3 4 5
OUTPUT FORMAT:
* Line 1: The minimum distance that Farmer John has to travel to reach
11
OUTPUT DETAILS:
The best path for Farmer John is (0, 0); (-1, 0); (-2, 0); (-2, 1);
(-2, 2); (-2, 3); (-2, 4); (-1, 4); (0, 4); (0, 3); (1, 3); and (1,
4 ******* . . . .
3 * M . * . . . .
Y 2 * . M B M . M .
1 * M . M . M . .
0 ***** . . . . .
-1 . . . . . . . .
-2-1 0 1 2 3 4 5
This is a classic 'Flood fill' algorithm. The idea is that one seeds a 'flood
fill' with an initial point followed by massive recursion to find the points
around that point.
4 .. . . .
3 .. . . .
2 .. * . .
1 .. . . .
0 .. . . .
01 2 3 4
one can easily imagine starting at point 2,2 and then examining points around
it after marking those points with the 'distance' from the initial point:
4 . . . . .
3 . . 1 . .
2 . 1 * 1 .
1 . . 1 . .
0 . . . . .
0 1 2 3 4
and then examining points around those 1's:
4 . . 2 . .
3 . 2 1 2 .
2 2 1 * 1 2
1 . 2 1 2 .
0 . . 2 . .
0 1 2 3 4
and so on until all distances are determined:
4|4 3 2 3 4
3|3 2 1 2 3
2|2 1 * 1 2
1|3 2 1 2 3
0|4 3 2 3 4
+---------
0 1 2 3 4
Adding in obstacles just makes some of the distances a bit different since
certain cells can not be used in the recursive search. Here is the flooded
version of the sample input data:
4| 6 7 8 9 10 11 10 9
3| 5 M 9 10 11 10 9 8
Y 2| 4 5 M B M 11 M 7
1| 3 M 1 M 3 M 5 6
0| 2 1 * 1 2 3 4 5
-1| 3 2 1 2 3 4 5 6
+-----------------------
-2 -1 0 1 2 3 4 5
X
The final '11' has not been written on to the 'B' square on which Bessie sits,
but it's clear that 11 is the answer.
check(x,y,dist) {
if (dist > matrix[x,y]) return;
matrix[x,y] = dist;
if (validsubscript (x+1, y ) check (x+1, y , dist+1);
if (validsubscript (x-1, y ) check (x-1, y , dist+1);
if (validsubscript (x , y+1) check (x , y+1, dist+1);
if (validsubscript (x , y-1) check (x , y-1, dist+1);
}
The pleasing intuitive brevity, though, is nothing but a trap. Why? Because,
as shown, the subprogram will quickly recurse to check(x+1, ...), check
(x+2, ...) and so on down the x axis instead of the geometrically nice
circular pattern exhibited a few paragraphs back. Will the algorithm still get
the right answer? Yes! Is there a way to implement the algorithm that will
take longer to get to the right answer? Probably not.
Instead, one needs to implement a FIFO queue structure so that all four of the
'next elements to search' are queued before any of them is examined. Bonus
performance for knowing if an element is already queued (and thus avoiding
requeueing it). Note that one should requeue elements whose value has changed
-- but it's hardly ever an advantage to have the same element on the queue
more than once.
Aside: queues can be nicely implemented with linked lists. Such lists are
slightly tricky to get 'right the first time' and sometimes are implemented
to allocate a tiny bit of storage for each element added to the list. In
contest programming, one might as well just make a big array and circle
through it. If you need more space than the array allows, you would have
needed more linked-list space -- and failed very late in the program's
execution. Better to expose the potential failure up front!
The final challenge in this task was the coordinate scheme: it starts at some
large negative number, so all subscripts need to be shifted into a valid
range. The first program below does this with #define's; the second explicitly
codes the shift into each subscript.
My solution is intended to be straightforward with the tiny trick of using a
bit more storage to set up a 'border' around the edges of the matrix. This
avoids having to validate every possible enqueueing to ensure the subscripts
will not go out of bounds for the array:
#include <stdio.h>
short field[2*RANGE+5][2*RANGE+5];
char done[2*RANGE+5][2*RANGE+5], queued[2*RANGE+5][2*RANGE+5];
tryenq (x,y,thisdist) {
if (FIELD(x,y) != 0 && thisdist >= FIELD(x,y)) return;
if (QUEUED(x,y)) return;
QUEUED(x,y) = 1;
FIELD(x,y) = thisdist;
if (++nq >= 790000) exit (9);
queue[tail].x = x;
queue[tail].y = y;
if (++tail >= 800000) tail = 0;
}
main () {
FILE *fin = fopen ("mud.in", "r");
FILE *fout = fopen ("mud.out", "w");
int X, Y, N, i, j, A, B;
/* enqueue if needed: */
if (DONE(x,y)) continue;
DONE(x,y) = 1;
tryenq(x+1, y , FIELD(x,y)+1);
tryenq(x-1, y , FIELD(x,y)+1);
tryenq(x , y+1, FIELD(x,y)+1);
tryenq(x , y-1, FIELD(x,y)+1);
}
Richard Peng's solution is a bit shorter (as usual). Among the techniques for
compaction:
The 'dir' array of the four pairs of integers that describe the four
potential squares to be newly examined
Using array subscripts rather than an structure for storing the queue
(probably a bit more obscure to understand if you look at the program
six months later)
Omission of tagging to prevent extra queueing/checking
Inclusion of negative elements in the 'vis' array to prevent extra
processing (probably a big win)
#include <cstdio>
#include <cstring>
int main () {
int i, j;
freopen ("mud.in", "r", stdin);
freopen ("mud.out", "w", stdout);
r = 1010; c = 1010; shif = 505;
tai = 0;
scanf ("%d%d%d", &x, &y, &n);
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
vis[i][j] = -1;
for (i = 0; i < n; i++){
scanf ("%d%d", &a, &b);
vis[a+shif][b+shif] = -2;
}
tai = 0;
add (shif, shif, 0);
for (i = 0; i < tai; i++)
for (j = 0; j < 4; j++)
add (q[i][0]+dir[j][0], q[i][1]+dir[j][1], vis[q[i][0]][q[i][1]]
+1);
printf ("%d\n", vis[x+shif][y+shif]);
return 0;
}
GOLD PROBLEMS
*****************************************************************************
Farmer John has decided to reward his cows for their hard work by taking them
on a tour of the big city! The cows must decide how best to spend their free
time.
Fortunately, they have a detailed city map showing the L (2 <= L <= 1000)
major landmarks (conveniently numbered 1.. L) and the P (2 <= P <= 5000)
unidirectional cow paths that join them. Farmer John will drive the cows to a
starting landmark of their choice, from which they will walk along the cow
paths to a series of other landmarks, ending back at their starting landmark
where Farmer John will pick them up and take them back to the farm. Because
space in the city is at a premium, the cow paths are very narrow and so travel
along each cow path is only allowed in one fixed direction.
While the cows may spend as much time as they like in the city, they do tend
to get bored easily. Visiting each new landmark is fun, but walking between
them takes time. The cows know the exact fun values F_i (1 <= F_i <= 1000) for
each landmark i.
The cows also know about the cowpaths. Cowpath i connects landmark L1_i to
L2_i (in the direction L1_i -> L2_i) and requires time T_i (1 <= T_i <= 1000)
to traverse.
In order to have the best possible day off, the cows want to maximize the
average fun value per unit time of their trip. Of course, the landmarks are
only fun the first time they are visited; the cows may pass through the
landmark more than once, but they do not perceive its fun value again.
Furthermore, Farmer John is making the cows visit at least two landmarks, so
that they get some exercise during their day off.
Help the cows find the maximum fun value per unit time that they can achieve.
INPUT FORMAT:
* Lines L+2..L+P+1: Line L+i+1 describes cow path i with three space-separated
integers: L1_i, L2_i, and T_i
5 7
30
10
10
5
10
1 2 3
2 3 2
3 4 5
3 5 2
4 5 5
5 1 3
5 2 2
OUTPUT FORMAT:
* Line 1: A single number given to two decimal places (do not perform
explicit rounding), the maximum possible average fun per unit time, or 0 if
the cows cannot plan any trip at all in accordance with the above rules.
6.00
OUTPUT DETAILS:
The trip 1 -> 2 -> 3 -> 5 -> 1 has a total fun value of 60 and a length of 10
units for an average fun per unit time of 6. The trip 2 -> 3 -> 5 -> 2 only
has an average fun per unit time of 30/6 = 5, and any trip involving landmark
4 has an average fun per unit time of less than 4.
This problem involves a graph in which each edge e has an associated length
L(e) and fun value F(e). Our goal is to find a directed cycle C minimizing
L(C) / F(C), where L(C) denotes the total length of all edges in C and F(C)
denotes the total fun value of all edges in C (note: the actual problem asks
us to maximize F(C) / L(C), but I've converted it to a minimization problem
since this is more common when we discuss shortest path type problems).
To solve this problem quickly, we employ a common trick: binary search on the
answer. Let us make a guess that the answer is X. By running one instance of
the Bellman-Ford shortest path algorithm (in O(LP) time), we will be able to
tell if this guess is too high or too low, thereby homing in on the correct
answer. The one feature of the Bellman-Ford algorithm we use here is the fact
that it can detect whether or not a negative-length direct cycle exists in a
graph (we won't go into how this is done here, since this is a common
algorithm).
How can negative cycle detection tell us if our guess X is too high or too
low? Well, we would like to check if the minimum value of L(C)/F(C) over all
cycles C is less than X (i.e., if there exists a cycle C such that L(C)/F(C)
<= X). If so, then our guess is too high; otherwise it is too low. But asking
whether there exists a cycle C such that L(C)/F(C) <= X is the same as asking
whether there exists a cycle C such that L(C) <= X F(C), which is the same as
asking whether there exists a cycle C such that L(C) - X F(C) <= 0. So if we
define the cost of each edge e as Z(e) = L(e) - X F(e), then this turns into a
negative cycle detection problem with respect to the Z(e)'s!
program sightsee;
const
finp = 'sightsee.in';
fout = 'sightsee.out';
maxn = 1000 + 5;
eps = 1e-4;
type
nodeptr = ^node;
node = record
p, len : longint;
next : nodeptr;
end;
var
n, m : longint;
var
tmp : nodeptr;
begin
end;
procedure init;
var
i : longint;
x, y, c : longint;
begin
read(n, m);
for i := 1 to n do read(cost[i]);
for i := 1 to m do
begin
read(x, y, c);
create(x, y, c);
end;
end;
begin
end;
var
h, t, i : longint;
tmp : nodeptr;
v : extended;
begin
check := true;
h := 0; t := 0;
for i := 1 to n do
begin
inc(t); queue[t] := i; hash[i] := true;
dist[i] := 0; edge[i] := 0;
end;
while (h <> t) do
begin
h := nxt(h);
tmp := a[queue[h]];
begin
begin
dist[tmp^.p] := dist[queue[h]] + v;
edge[tmp^.p] := edge[queue[h]] + 1;
begin
t := nxt(t);
queue[t] := tmp^. p;
end;
end;
end;
hash[queue[h]] := false;
end;
check := false;
end;
procedure work;
var
l, r, mid : extended;
begin
l := 0; r := 1000;
begin
mid := (l + r) / 2;
end;
writeln(l : 0 : 2);
end;
begin
init;
work;
close(input); close(output);
end.
Like so many others, the cows have developed very haughty tastes and will no
longer graze on just any grass. Instead, Farmer John must purchase gourmet
organic grass at the Green Grass Grocers store for each of his N (1 <= N <=
100,000) cows.
Each cow_i demands grass of price at least A_i (1 <= A_i <= 1,000,000,000) and
with a greenness score at least B_i (1 <= B_i <= 1,000,000,000). The GGG store
has M (1 <= M <= 100,000) different types of grass available, each with a
price C_i (1 <= C_i <= 1,000,000,000) and a greenness score of D_i (1 <= D_i
<= 1,000,000,000). Of course, no cow would sacrifice her individuality, so no
two cows can have the same kind of grass.
Help Farmer John satisfy the cows' expensive gourmet tastes while spending as
little money as is necessary.
INPUT FORMAT:
4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4
OUTPUT FORMAT:
12
OUTPUT DETAILS:
Cow 1 eats grass 2 at cost 2, cow 2 eats grass 3 at cost 4, cow 3 eats grass 6
at cost 2, and cow 4 eats grass 7 at cost 4, for a total cost of 12.
The greedy solution works for this task. The first observation is if we sort
the requests and grasses by decreasing order of green-ness, the set of grass
we need to consider for each request is precisely the set of all grass that
hasn't been used yet that has a higher greenness. So we can add grasses to the
set as we 'sweep' by them and remove the grasses as we use them.
Let's just consider the prices. The claim is that at each moment, we can pick
the cheapest grass that will satisfy the cow. This is true since suppose we
pick a more expensive grass and use the cheaper one later, we can swap the
choices while keeping both cows satisfied without increasing the total cost.
Now the problem becomes a data structure problem, we need to support the
following operations: insertion, deletion, find the first element with key
bigger than a given value and we want to do each operation in O(logn) time.
This can be done using STL set. It's also possible to do this without STL
using a binary index tree by first assigning values from 1 to n to the prices,
then construct a full binary tree with the prices at leafs and track on each
node whether the subtree below has values. Both give O(nlogn) solutions.
#include <iterator>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
int main () {
int n, m, i, q, w;
int r = m - 1;
__int64 ans = 0;
a.clear ();
for (i=n-1;i>=0;i--) {
while (1) {
if (r < 0) break;
r--;
else break;
return 0;
ans += (*d).first;
a.erase (d);
return 0;
FJ is about to take his N (1 <= N <= 30,000) cows to the annual "Farmer of the
Year" competition. In this contest every farmer arranges his cows in a line
and herds them past the judges.
The contest organizers adopted a new registration scheme this year: simply
register the initial letter of every cow in the order they will appear (e.g.,
If FJ takes Bessie, Sylvia, and Dora in that order, he just registers BSD).
After the registration phase ends, every group is judged in increasing
lexicographic order (i.e., alphabetical order) according to the string of the
initials of the cows' names.
FJ is very busy this year and has to hurry back to his farm, so he wants to be
judged as early as possible. He decides to rearrange his cows, who have
already lined up, before registering them.
FJ marks a location for a new line of the competing cows. He then proceeds to
marshal the cows from the old line to the new one by repeatedly sending either
the first or last cow in the (remainder of the) original line to the end of
the new line. When he's finished, FJ takes his cows for registration in this
new order.
Given the initial order of his cows, determine the least lexicographic string
of initials he can make this way.
PROBLEM NAME: bclgold
INPUT FORMAT:
6
A
C
D
B
C
B
INPUT DETAILS:
OUTPUT FORMAT:
The least lexicographic string he can make. Every line (except perhaps the
last one) contains the initials of 80 cows ('A'..'Z') in the new line.
ABCBCD
OUTPUT DETAILS:
This problem can be solved with dynamic programming on the intervals of cows
but there is also a simple greedy strategy.
Between the two cows in the edges, you must always pick the cow with the
smallest initial letter. If both cows have the same initial letter in order to
decide you must look a little bit deeper and check the second cows in the
line's edges or the third ones if those are equal and so on until you find two
cows that are different. Then you pick the cow from the side of the smallest
one.
This can be implemented in O(N^2) but we can achieve O(NlogN) by using suffix
arrays.
The O(N^2)
#include<cstdio>
char S[2010],ln=0;
void prnt(char a) {
if(ln==80) {printf("\n");ln=0;}
printf("%c",a);ln++;
}
int main() {
int i,j,N,pi,pj,val;
freopen("bcl.in" ,"r",stdin );
freopen("bcl.out","w",stdout);
scanf("%d",&N);
for(i=0;i<N;i++) scanf(" %c ",S+i);
i=0,j=N-1;
while(i<=j) {
if(S[i]<S[j]) {prnt(S[i]);i++;}
else if(S[i]>S[j]) {prnt(S[j]);j--;}
else {
pi=i+1;pj=j-1;val=S[i];
while( pj-pi>1 && S[pi]==S[pj]) {pi++,pj--;}
if(S[pi]<S[pj]) prnt(S[i]),i++;
else prnt(S[j]),j--;
}
}
printf("\n");
return 0;
}
And the O(NlogN)
#include<cstdio>
#include<cstring>
#include<cstdlib>
char S[2*MAXN];
int N,ln=0;
int o[2][2*MAXN], t[2*MAXN][2];
int A[2*MAXN], B[2*MAXN], C[2*MAXN], D[2*MAXN];
void prnt(char a) {
if(ln==80) {printf("\n");ln=0;}
printf("%c",a);ln++;
}
int main() {
int i, j, jj, x, k;
freopen("bcl.in" ,"r",stdin );
freopen("bcl.out","w",stdout);
scanf("%d",&N);
for(i=0;i<N;i++) {
scanf(" %c ",S+i);
S[N+i] = S[i];
}
memset(A, 0, sizeof(A));
for (i = 0; i < 2*N; ++i) A[(int)(S[i]-'A')] = 1;
for (i = 1; i < 26; ++i) A[i] += A[i-1];
for (i = 0; i < 2*N; ++i) o[0][i] = A[(int)(S[i]-'A')];
x=0;
for (j = 0, jj = 1, k = 0; jj < N && k < 2*N; ++j, jj <<= 1) {
memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));
x ^= 1;
o[x][D[0]] = k = 1;
for (i = 1; i < 2*N; ++i)
o[x][D[i]] = (k += (t[D[i]][0] != t[D[i-1]][0] ||
t[D[i]][1] != t[D[i-1]][1]));
}
i=0,j=N-1;
while(i<=j) {
if(S[i]<S[j]) {prnt(S[i]);i++;}
else if(S[i]>S[j]) {prnt(S[j]);j--;}
else if(o[x][i]<o[x][N+j]) {prnt(S[i]);i++;}
else {prnt(S[j]);j--;}
}
printf("\n");
return 0;
}
**********************************************************************
Bessie will visit the landmarks in a particular order. Since the landmarks
closer to the origin are more important to Farmer John, she always heads for
the unvisited landmark closest to the origin. No two landmarks will be the
same distance away from the origin.
Help Bessie determine the maximum number of landmarks she can visit before the
day ends.
INPUT FORMAT:
25 5
10
-3
-7
INPUT DETAILS:
Bessie has 25 minutes before sundown, and there are 5 landmarks located at
positions 10, -3, 8, -7, and 1.
OUTPUT FORMAT:
OUTPUT DETAILS:
Bessie sequentially visits the landmarks at locations 1, -3, -7, and 8, after
which she has traveled a total of 24 minutes. She cannot visit the next
intended landmark at position 10, since this would extend her total travel
time to 26 minutes.
This is not an optimization problem (it is not one where you find an optimal
route). The route procedure was explicit: visit the next unvisited node that
is closest to the origin. We know that in one dimension, distance is the
absolute value between two points so the distance to the origin for point Z is
just |Z|, the absolute value of Z.
Thus, the problem devolves into finding the route (sorting the absolute value
of the input data) and then simulating the traversal (i.e., visit successive
landmarks until the time runs out). The problem was unclear about whether the
time limit was < T or <= T, but the test data did not exploit this.
The only 'tricky part' is that the data was chosen such that an O(N 2) sort
would not succeed on the largest test cases. One needed to invoke a system
sort (e.g., qsort) or include a 'good' sort in the submitted program.
#include <stdlib.h>
int list[50000];
main() {
/* start visiting: */
bessloc = 0;
nvisit = 0;
timevisit = 0;
nvisit++;
bessloc = list[i];
exit (0);
All K (1 <= K <= 1,000) of the cows are participating in Farmer John's annual
reading contest. The competition consists of reading a single book with N (1
<= N <= 100,000) pages as fast as possible while understanding it.
Cow i has a reading speed S_i (1 <= S_i <= 100) pages per minute, a maximum
consecutive reading time T_i (1 <= T_i <= 100) minutes, and a minimum rest
time R_i (1 <= R_i <= 100) minutes. The cow can read at a rate of S_i pages
per minute, but only for T_i minutes at a time. After she stops reading to
rest, she must rest for R_i minutes before commencing reading again.
Determine the number of minutes (rounded up to the nearest full minute) that
it will take for each cow to read the book.
INPUT FORMAT:
10 3
2 4 1
6 1 5
3 3 3
INPUT DETAILS:
The book has 10 pages; 3 cows are competing. The first cow reads at a rate of
2 pages per minute, can read for at most 4 minutes at a time, and must rest
for 1 minute after reading. The second reads at a rate of 6 pages per minute,
can read for at most 1 minute at a time, and must rest 5 minutes after
reading. The last reads at a rate of 3 pages per minute, can read for at most
3 minutes at a time, and must rest for 3 minutes after reading.
OUTPUT FORMAT:
OUTPUT DETAILS:
The first cow can read 8 pages in 4 minutes, rest for 1 minute, and read the
last 2 pages in a minute. The second reads 6 pages in a minute, rests for 5
minutes, and finishes in the next minute. The last reads 9 pages in 3 minutes,
rests for 3 minutes, and finishes in the next minute.
This is an 'ad hoc' programming problem: just 'figure it out' and make it
work. No commonly used algorithm or anything like that.
#include <stdio.h>
#include <stdlib.h>
main() {
pages = N;
busy = 0;
pages -= speed;
busy++;
minutes += rest;
busy = 0;
exit (0);
Richard Peng (and a host of others), on the other hand, created tricky (in my
opinion) formulae that would yield the answer at least somewhat directly (at
least without looping). One of these solutions is below. Unfortunately,
another coach who tried the same thing got wrong answers on some of the cases.
Half those who submitted solutions to this problem missed the final test case;
it appears at least some of them tried the trickier math procedures.
#include <cstdio>
int ans, n, r, s, t;
int main() {
int ct;
while (ct--) {
ans = (s+t)*(n/(r*s));
ans += ((n%(r*s))+r-1)/r;
printf("%d\n",ans);
return 0;
Farmer John's farm was flooded in the most recent storm, a fact only
aggravated by the information that his cows are deathly afraid of water. His
insurance agency will only repay him, however, an amount depending on the size
of the largest "lake" on his farm.
The farm is represented as a rectangular grid with N (1 <= N <= 100) rows and
M (1 <= M <= 100) columns. Each cell in the grid is either dry or submerged,
and exactly K (1 <= K <= N*M) of the cells are submerged. As one would expect,
a lake has a central cell to which other cells connect by sharing a long edge
(not a corner). Any cell that shares a long edge with the central cell or
shares a long edge with any connected cell becomes a connected cell and is
part of the lake.
INPUT FORMAT:
* Lines 2..K+1: Line i+1 describes one submerged location with two
space separated integers that are its row and column: R and C
3 4 5
3 2
2 2
3 1
2 3
1 1
INPUT DETAILS:
The farm is a grid with three rows and four columns; five of the cells are
submerged. They are located in the positions (row 3, column 2); (row 2, column
2); (row 3, column 1); (row 2, column 3); (row 1, column 1):
# . . .
. # # .
# # . .
OUTPUT FORMAT:
OUTPUT DETAILS:
The solution relies on simple scanning of the 'lake' looking for water spots.
When one is found, a count is commenced for that spot and, recursively, its
neighbors (see the four invocations of 'lsize' inside 'lsize' itself). Each
spot that is scanned is marked so that scanning will not be attempted for that
spot again. Thus, the algorithm is linear in the number of squares scanned,
O(R*C).
#include <stdio.h>
#include <stdlib.h>
int N, M, K, map[MAX_N+2][MAX_N+2];
map[i][j] = 0;
if (map[i][j-1]) a += lsize(i,j-1);
if (map[i][j+1]) a += lsize(i,j+1);
if (map[i-1][j]) a += lsize(i-1,j);
if (map[i+1][j]) a += lsize(i+1,j);
return a;
}
int main(void) {
FILE *fp;
int i, j, k, best=0;
map[i][j] = 1;
fclose (fp);
if (map[i][j])
fclose (fp);
return 0;
SILVER PROBLEMS
*****************************************************************************
Farmer John wants the cows to prepare for the county jumping competition, so
Bessie and the gang are practicing jumping over hurdles. They are getting
tired, though, so they want to be able to use as little energy as possible to
jump over the hurdles.
Obviously, it is not very difficult for a cow to jump over several very short
hurdles, but one tall hurdle can be very stressful. Thus, the cows are only
concerned about the height of the tallest hurdle they have to jump over.
The cows' practice room has N (1 <= N <= 300) stations, conveniently labeled
1..N. A set of M (1 <= M <= 25,000) one-way paths connects pairs of stations;
the paths are also conveniently labeled 1..M. Path i travels from station S_i
to station E_i and contains exactly one hurdle of height H_i (1 <= H_i <=
1,000,000). Cows must jump hurdles in any path they traverse.
The cows have T (1 <= T <= 40,000) tasks to complete. Task i comprises two
distinct numbers, A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N), which connote
that a cow has to travel from station A_i to station B_i (by traversing over
one or more paths over some route). The cows want to take a path the minimizes
the height of the tallest hurdle they jump over when traveling from A_i to
B_i. Your job is to write a program that determines the path whose tallest
hurdle is smallest and report that height.
INPUT FORMAT:
5 6 3
1 2 12
3 2 8
1 3 5
2 5 3
3 4 4
2 4 8
3 4
1 2
5 1
OUTPUT FORMAT:
* Lines 1..T: Line i contains the result for task i and tells the
smallest possible maximum height necessary to travel between the stations.
Output -1 if it is impossible to travel between the two stations.
-1
OUTPUT DETAILS:
Query #1: The best way is to simply travel on the path from station 3 to
station 4.
Query #2: There is a path from station 1 to station 2, but a better way
Query #3: There are no paths that start at station 5, so it is clear that
First of all, it is clear that this problem can be converted into a (directed)
graph, and for each of the T queries, we wish to find the shortest path
between two nodes A and B.
One possible solution is for every query, use either a single-source shortest
path algorithm (such as Dijkstra) or do a depth-first search to find the
shortest path. However, this can take up to O(N 2) time for each query, and
would then have a total running time of O(N 2 T), which is too large for this
problem's constraints.
Thus we instead want to find a way to precompute all of the shortest paths
beforehand. We do this by initializing all distances between two nodes A and B
to the cost of the edge between A and B, or infinity if no such edge exists.
Then we run the standard Floyd-Warshall algorithm (more info can be found in
the Training pages or here) to compute the shortest paths, with one
difference: If cost (a, b, c,...) represents the cost of traveling from a to b
and then from b to c, etc., then instead of
we now have
(The proof that this method does correctly find the shortest path is left to
the reader.)
Our total running time is thus O(N 3 + T), since the Floyd-Warshall takes O(N 3)
time to compute the shortest paths, and each query takes O(1) time.
#include <cstdio>
#include <cstring>
int N, M, T;
int main () {
// initialize to 'infinity'
int a, b, c;
// input data
// output results
a--, b--;
fprintf (fout, "%d\n", dist [a][b] < INF ? dist [a][b] : -1);
return 0;
Farmer John has a list of M (1 <= M <= 1,000) possibly overlapping intervals
in which he is available for milking. Each interval i has a starting hour (0
<= starting_hour_i < N), an ending hour (starting_hour_i < ending_hour_i <=
N), and a corresponding efficiency (1 <= efficiency_i <= 1,000,000) which
indicates how many gallons of milk that he can get out of Bessie in that
interval. Farmer John starts and stops milking at the beginning of the
starting hour and ending hour, respectively. When being milked, Bessie must be
milked through an entire interval.
Even Bessie has her limitations, though. After being milked during any
interval, she must rest R (1 <= R <= N) hours before she can start milking
again. Given Farmer Johns list of intervals, determine the maximum amount of
milk that Bessie can produce in the N hours.
INPUT FORMAT:
* Lines 2..M+1: Line i+1 describes FJ's ith milking interval with
three space-separated integers: starting_hour_i, ending_hour_i, and
efficiency_i
12 4 2
1 2 8
10 12 19
3 6 24
7 10 31
INPUT DETAILS:
Bessie wants to schedule the next 12 hours; Farmer John has four intervals in
which he can milk her; Bessie must rest 2 hours after every milking. The first
interval lasts from hour 1 to hour 2, the second from hour 10 to hour 12, the
third from hour 3 to hour 6, and the fourth from hour 7 to hour 10. Farmer
John can get 8, 19, 24, and 31 gallons of milk, respectively, from Bessie in
those intervals.
OUTPUT FORMAT:
43
OUTPUT DETAILS:
If Bessie uses the first interval, she cannot use the third because she needs
2 hours of rest. If she uses the second, she cannot use the fourth. Lastly,
if she uses the third, she cannot use the fourth. The best situation is
choosing the second and third intervals, producing 43 gallons of milk.
<="j.start})" i.end and> What does this mean? Well, the optimal solution for
intervals 1...j either includes interval j or it doesn't. To cover both cases,
we take the best of two solutions: the best solution for intervals 1...j that
_doesn't_ contain j, and the best solution for intervals 1...j that _does_
contain j. In the first case, the optimal solution value is just E(j-1), since
we only get to use intervals 1...j-1. In the second case, we get to count the
efficiency of interval j towards our total value, and then we finish off our
solution by adding in E(i) for the "best" preceding interval i (where we only
consider those intervals i ending before j starts).
If you would like to test whether or not you understand the principle behind
this solution well, consider the following related problem: you are given n
intervals that collectively cover the range 0....1,000,000, where each
interval has an associated cost. Your goal is to find a minimum-cost subset of
the intervals that still covers the range 0....1,000,000. Target running time:
O(n^2), or O(n log n) if you are extra clever.
#include <stdio.h>
#include <stdio.h>
typedef struct {
int start;
int end;
int efficiency;
} Interval;
Interval I[MAX_M];
int N, M, K, Best[MAX_M];
int main(void)
int i, j, best=-1;
FILE *fp;
fclose (fp);
Best[j] = I[j].efficiency;
fclose (fp);
FJ is about to take his N (1 <= N <= 2,000) cows to the annual "Farmer of the
Year" competition. In this contest every farmer arranges his cows in a line
and herds them past the judges.
The contest organizers adopted a new registration scheme this year: simply
register the initial letter of every cow in the order they will appear (i.e.,
If FJ takes Bessie, Sylvia, and Dora in that order he just registers BSD).
After the registration phase ends, every group is judged in increasing
lexicographic order according to the string of the initials of the cows'
names.
FJ is very busy this year and has to hurry back to his farm, so he wants to be
judged as early as possible. He decides to rearrange his cows, who have
already lined up, before registering them.
FJ marks a location for a new line of the competing cows. He then proceeds to
marshal the cows from the old line to the new one by repeatedly sending either
the first or last cow in the (remainder of the) original line to the end of
the new line. When he's finished, FJ takes his cows for registration in this
new order.
Given the initial order of his cows, determine the least lexicographic string
of initials he can make this way.
PROBLEM NAME: bcl
INPUT FORMAT:
INPUT DETAILS:
OUTPUT FORMAT:
The least lexicographic string he can make. Every line (except perhaps the
last one) contains the initials of 80 cows ('A'..'Z') in the new line.
OUTPUT DETAILS:
#1 ACDBCB
#2 CDBCB A
#3 CDBC AB
#4 CDB ABC
#5 CD ABCB
#6 D ABCBC
#7 ABCBCD
This problem can be solved with dynamic programming on the intervals of cows
but there is also a simple greedy strategy.
Between the two cows in the edges, you must always pick the cow with the
smallest initial letter. If both cows have the same initial letter in order to
decide you must look a little bit deeper and check the second cows in the
line's edges or the third ones if those are equal and so on until you find two
cows that are different. Then you pick the cow from the side of the smallest
one.
This can be implemented in O(N^2) but we can achieve O(NlogN) by using suffix
arrays.
char S[2010],ln=0;
void prnt(char a) {
if(ln==80) {printf("\n");ln=0;}
printf("%c",a);ln++;
}
int main() {
int i,j,N,pi,pj,val;
freopen("bcl.in" ,"r",stdin );
freopen("bcl.out","w",stdout);
scanf("%d",&N);
for(i=0;i<N;i++) scanf(" %c ",S+i);
i=0,j=N-1;
while(i<=j) {
if(S[i]<S[j]) {prnt(S[i]);i++;}
else if(S[i]>S[j]) {prnt(S[j]);j--;}
else {
pi=i+1;pj=j-1;val=S[i];
while( pj-pi>1 && S[pi]==S[pj]) {pi++,pj--;}
if(S[pi]<S[pj]) prnt(S[i]),i++;
else prnt(S[j]),j--;
}
}
printf("\n");
return 0;
}
#include<cstdio>
#include<cstring>
#include<cstdlib>
char S[2*MAXN];
int N,ln=0;
int o[2][2*MAXN], t[2*MAXN][2];
int A[2*MAXN], B[2*MAXN], C[2*MAXN], D[2*MAXN];
void prnt(char a) {
if(ln==80) {printf("\n");ln=0;}
printf("%c",a);ln++;
}
int main() {
int i, j, jj, x, k;
freopen("bcl.in" ,"r",stdin );
freopen("bcl.out","w",stdout);
scanf("%d",&N);
for(i=0;i<N;i++) {
scanf(" %c ",S+i);
S[N+i] = S[i];
}
memset(A, 0, sizeof(A));
for (i = 0; i < 2*N; ++i) A[(int)(S[i]-'A')] = 1;
for (i = 1; i < 26; ++i) A[i] += A[i-1];
for (i = 0; i < 2*N; ++i) o[0][i] = A[(int)(S[i]-'A')];
x=0;
for (j = 0, jj = 1, k = 0; jj < N && k < 2*N; ++j, jj <<= 1) {
memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));
x ^= 1;
o[x][D[0]] = k = 1;
for (i = 1; i < 2*N; ++i)
o[x][D[i]] = (k += (t[D[i]][0] != t[D[i-1]][0] ||
t[D[i]][1] != t[D[i-1]][1]));
}
i=0,j=N-1;
while(i<=j) {
if(S[i]<S[j]) {prnt(S[i]);i++;}
else if(S[i]>S[j]) {prnt(S[j]);j--;}
else if(o[x][i]<o[x][N+j]) {prnt(S[i]);i++;}
else {prnt(S[j]);j--;}
}
printf("\n");
return 0;
}
GOLD PROBLEMS
*****************************************************************************
Farmer John's cows are getting restless about their poor telephone service;
they want FJ to replace the old telephone wire with new, more efficient wire.
The new wiring will utilize N (2 <= N <= 100,000) already-installed telephone
poles, each with some height_i meters (1 <= height_i <= 100). The new wire
will connect the tops of each pair of adjacent poles and will incur a penalty
cost C * the two poles' height difference for each section of wire where the
poles are of different heights (1 <= C <= 100). The poles, of course, are in a
certain sequence and can not be moved. Farmer John figures that if he makes
some poles taller he can reduce his penalties, though with some other
additional cost. He can add an integer X number of meters to a pole at a cost
of X^2.
Help Farmer John determine the cheapest combination of growing pole heights
and connecting wire so that the cows can get their new and improved service.
INPUT FORMAT:
5 2
2
3
5
1
4
INPUT DETAILS:
There are 5 telephone poles, and the vertical distance penalty is $2/meter.
The poles initially have heights of 2, 3, 5, 1, and 4, respectively.
OUTPUT FORMAT:
* Line 1: The minimum total amount of money that it will cost Farmer
John to attach the new telephone wire.
15
OUTPUT DETAILS:
The best way is for Farmer John to raise the first pole by 1 unit and the
fourth pole by 2 units, making the heights (in order) 3, 3, 5, 3, and 4. This
costs $5. The remaining wiring will cost $2*(0+2+2+1) = $10, for a
total of $15.
Let H[i] be the original height of the i-th pole, and let f(n, h) be the
minimum cost for n poles with the n-th pole having height h. Then:
f(n, h) = (H[i]-h)^2 + min { -C*h + min { f(n-1, h')+C*h' } (for h' >= h),
low(n, h) and high(n, h) for all n, h can be computed in O(N*H) time; thus
f(n, h) can be computed in O(N*H) time as well. A final implementation detail:
an array of size O(N*H) exceeds the the memory limit, but only two "rows" of
the DP table are needed at a time, so an array of size 2*H is sufficient.
#include <cstdio>
huge = 2100000000;
pre = (i+1)%2;
cur = i%2;
for (bes1 = huge, j = 0; j<MAXH; j++){
bes[cur][j] = bes1+j*c;
ans = huge;
return 0;
For their physical fitness program, N (2 <= N <= 1,000,000) cows have decided
to run a relay race using the T (2 <= T <= 100) cow trails throughout the
pasture.
Each trail connects two different intersections (1 <= I1_i <= 1,000; 1 <= I2_i
<= 1,000), each of which is the termination for at least two trails. The cows
know the length_i of each trail (1 <= length_i <= 1,000), the two
intersections the trail connects, and they know that no two intersections are
directly connected by two different trails. The trails form a structure known
mathematically as a graph.
INPUT FORMAT:
2 6 6 4
11 4 6
4 4 8
8 4 9
6 6 8
2 6 9
3 8 9
OUTPUT FORMAT:
10
First, note that there cannot be more than T distinct nodes in our graph,
because there are exactly T edges in the graph, and each node is an endpoint
for at least two edges.
Assume we have the shortest path, from S to E, of length N. Then we can break
up this path into smaller paths whose lengths are powers of two. Thus, we can
compute, for each power of two that is no greater than N, the shortest path
between every pair of nodes that has a length of that power of two. This can
be done using a method similar to Floyd-Warshall in O(T 3 log N) time. (See the
code below for more details.)
After we compute the shortest paths mentioned above, we can compute shortest
paths, of length N, from S to every other node. We do this by breaking N up
into its binary representation, and for each power of two that occurs, we
compute shortest paths after adding in paths of length equal to this power.
This can be done in O(T2 log N) time. (Again, see the code below for more
details.) Thus, our overall runtime is O(T 3 log N).
#include <cstdio>
#include <cstring>
int N, V, T, S, E;
int main () {
// initialize arrays
check (S);
check (E);
int A, B, L;
check (A);
check (B);
// edges are paths of length 1
best [S] = 0;
// use a temporary array 'best2' to hold the new values, and copy them to the
old array afterward
return 0;
To avoid unsightly burns while tanning, each of the C (1 <= C <= 2500) cows
must cover her hide with sunscreen when they're at the beach. Cow i has a
minimum and maximum SPF rating (1 <= minSPF_i <= 1,000; minSPF_i <= maxSPF_i
<= 1,000) that will work. If the SPF rating is too low, the cow suffers
sunburn; if the SPF rating is too high, the cow doesn't tan at all.
The cows have a picnic basket with L (1 <= L <= 2500) bottles of sunscreen
lotion, each bottle i with an SPF rating SPF_i (1 <= SPF_i <= 1,000). Lotion
bottle i can cover cover_i cows with lotion. A cow may lotion from only one
bottle.
What is the maximum number of cows that can protect themselves while tanning
given the available lotions?
INPUT FORMAT:
3 2
3 10
2 5
1 5
6 2
4 1
INPUT DETAILS:
3 cows; 2 lotions. Cows want SPF ratings of 3..10, 2..5, and 1..5. Lotions
available: 6 (for two cows), 4 (for 1 cow). Cow 1 can use the SPF 6 lotion.
Either cow 2 or cow 3 can use the SPF 4 lotion. Only 2 cows can be covered.
OUTPUT FORMAT:
A single line with an integer that is the maximum number of cows that
can be protected while tanning
Why does this give an optimal solution? Let B denote a bottle of sunscreen
with the lowest SPF rating. If no cow is compatible with B, then clearly B
cannot be assigned in any solution, so we can ignore B. Otherwise, let C be
the cow having lowest maxSPF rating that is compatible with B. We claim that
there is always an optimal solution in which C is paired with B, so it is
"safe" to make this assignment as our algorithm progresses (i.e., it will
never make a wrong decision and end up in a situation where an optimal
solution is no longer reachable). To see this, suppose there is an optimal
solution S where C is _not_ paired with B, and consider a few cases:
(i) C and B are both unassigned in S. This case cannot happen, since we could
assign C with B and obtain an even better solution, contradicting the
optimality of S.
(ii) C is assigned in S but B is not. Here, by reassigning C to B, we obtain
an equally-good solution in which C and B are assigned.
(iv) C and B are both assigned in S. Let B' be the bottle assigned to C, and
C' be the cow assigned to B. Here, you can check that it is valid to reassign
C with B and C' with B', giving us an equally good assignment in which C and B
are assigned.
In terms of running time, one can implement either of the two algorithms above
in O(n log n) time. One way to do this is the following (in the case of the
first algorithm above): We first sort the bottles by SPF rating and the cows
by minSPF rating. We then scan the bottles in order and maintain a min-heap on
the cows (keyed on maxSPF) with minSPF lower than the SPF of our current
bottle. For each bottle B in order, we match it with the minimum cow from the
heap (after first removing any cows from the heap having maxSPF less than the
SPF of B).
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
int n,m,ans;
pair<int,int> cow[MAXN],lotion[MAXN];
priority_queue<int> q;
void process(){
int i,i1;
while(!q.empty()) q.pop();
sort(cow,cow+n);
sort(lotion,lotion+m);
for(ans=i=i1=0;i<m;i++){
while((i1<n)&&(cow[i1].first<=lotion[i].first))
q.push(-cow[i1++].second);
while((!q.empty())&&(-(q.top())<lotion[i].first))
q.pop();
while((!q.empty())&&(lotion[i].second--)){
ans++;
q.pop();
int main(){
int i,j;
freopen("tanning.in","r",stdin);
freopen("tanning.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d%d",&cow[i].first,&cow[i].second);
for(i=0;i<m;i++)
scanf("%d%d",&lotion[i].first,&lotion[i].second);
ans=0;
process();
printf("%d\n",ans);
return 0;