Contents

## Wetlands

The Friends of Wetlands have dammed a creek to provide water for the nearby wetlands. During each month some rainwater flows into the dam, and then at the end of each month precisely 10 megalitres of water are released into the wetlands. If the dam contains less than 10 megalitres at the end of the month, the entire contents of the dam are released.

The local firefighters view the dam as a potential source of water to fight bushfires, and would like to know how much water there is likely to be in the dam in the height of the bushfire season in eight months' time. Your task is to use predicted rainfall figures to answer this question.

For example, suppose the predicted amounts of rainwater flowing into the dam for each of the eight months are 12, 9, 10, 7, 10, 13, 9 and 15 megalitres respectively. Assuming these figures are correct, after the first month the dam fills with 12 megalitres, and then 10 megalitres are taken (leaving 2). After the second month the dam fills to 2+9=11 megalitres, which is then reduced to 1. After the third month the dam fills to 11 megalitres and is again reduced to 1.

The fourth month is more interesting--here the dam only fills to 1+7=8 megalitres. Since the usual 10 megalitres cannot be taken, the dam is emptied completely. After the fifth month it fills to 10 and is again emptied, then it fills to 13 and reduces to 3, then fills to 12 and reduces to 2, and finally after the eighth month it fills to 17 and reduces to 7. Therefore your final answer for the firefighters is 7 megalitres.

### Solution

辣鸡模拟题

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <bits/stdc++.h> using namespace std; int x, now; int main() { freopen("wetin.txt","r",stdin); freopen("wetout.txt","w",stdout); for(int i = 1; i <= 8; ++ i) { scanf("%d",&x); now += x; if(now >= 10) now -= 10; else now = 0; } printf("%d",now); return 0; } |

## Superphone

It is almost time. After months of waiting and media hype, the new all-in-one mobile phone, music player and electric toothbrush is about to be released. You have been waiting outside the tall store for the last twelve hours hoping to be the first to get your hands on one of these new phones. In just a few minutes, the store is going to open.

Unfortunately, a large number of other people have also been milling about outside the store, they too wanting to be the first to purchase one of these new phones. To ensure that they don't beat you to it, you will not only have to sprint to the sales desk of the store, but you will need to ensure that you take the absolute fastest route to get there.

The store is a large building consisting of several floors. Each floor has a pair of escalators that connect to the floor above, as shown in the figure below. The left-hand side of the building has an escalator to the right-hand side of the floor above, and the right-hand side of the building has an escalator to the left-hand side of the floor above. All of these escalators move up. Also, on each floor you are able to (if you wish) sprint to the other side of the building to get to the escalator on the other side.

The doors of the store, where you are currently waiting, are located to the left of bottom floor. The sales desk, where you must purchase your phone, is located on the right of the top floor.

From your research, you know that different escalators move at different speeds, and some floors are more difficult to run through than others. Fortunately, you have carefully recorded precisely how many seconds it takes you to run up each individual escalator, as well as how many seconds it takes you to run from one side of each individual floor to the other.

Your task is to determine the minimum amount of time required to reach the sales desk of the building from the doors of the building.

### Solution

无智商选手并不会你们那么简单的算法，于是写了一发堆优化的dij就水过了。。。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include <bits/stdc++.h> using namespace std; const int N = 100050; int n, head[N*2], cnt, dis[N*2]; struct edge{int next,to,w;} e[N*6]; bool inq[N*2]; struct node { int dis,id; node(){} node(int _,int __){dis = _; id = __;} friend bool operator < (node a,node b) { return a.dis > b.dis; } }; void link(int u,int v,int w) { ++ cnt; e[cnt].next = head[u]; e[cnt].to = v; e[cnt].w = w; head[u] = cnt; ++ cnt; e[cnt].next = head[v]; e[cnt].to = u; e[cnt].w = w; head[v] = cnt; } int dij(int u,int v) { priority_queue<node> q; node ahead, next; int i; q.push(node(0,u)); memset(dis,0x3f,sizeof(dis)); dis[u] = 0; inq[0] = true; while(!q.empty()) { ahead = q.top(); q.pop(); inq[ahead.id] = false; for(i = head[ahead.id]; i ; i = e[i].next) { next.id = e[i].to; if(dis[next.id] > dis[ahead.id] + e[i].w) { dis[next.id] = dis[ahead.id] + e[i].w; next.dis = dis[next.id]; if(!inq[next.id]) q.push(next), inq[next.id] = true; } } } return dis[v]; } int main() { freopen("phonein.txt","r",stdin); freopen("phoneout.txt","w",stdout); int i, x, y, z; scanf("%d",&n); for(i = 1; i < n; ++ i) { scanf("%d%d%d",&x,&y,&z); link(i,i+n+1,x); link(i,i+n,y); link(i+n,i+1,z); } scanf("%d",&x); link(n,n+n,x); printf("%d",dij(1,n+n)); return 0; } |

## Mansion

It has been five years since you founded your highly successful online restaurant *Bytes and Nybbles*, and you have amassed a small fortune. In need of something to do with all this money, you decide to build an extremely large and luxurious mansion.

Of course you could never *live* in such a mansion--you would get lost trying to find your way from one end to the other. The only purpose of this mansion would be for people to look at it and admire it. You therefore need to choose a location for your mansion so as many people can see it as possible.

Your mansion will be built on a long road, as illustrated below. One side of the road is filled with houses, each of the same size. You have done your homework, and you have a complete listing of how many people live in each house. Your mansion will cover the width of w houses combined, and will be built on the other side of this road. Your aim is to choose a location so that as many people as possible live opposite your mansion.

For instance, consider the road above and suppose that w=4. There are four possible locations for your mansion, each illustrated below. In the first location you would have 3+2+5+1=11 people living opposite. In the second location you would have 2+5+1+4=12 people opposite, and in the third and fourth locations you would have 11 and 9 people respectively. The best you can do is 12 people, and so you build your mansion in the second location (to the envy of your neighbours).

Of course this is just an example--in reality the road might be much longer, and your mansion might be much larger. Your task is to write a computer program that can choose the best location for you.

### Solution

暴力枚举，维护前缀和即可

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <bits/stdc++.h> using namespace std; const int N = 100050; int n, w, a[N], ans; int main() { freopen("manin.txt","r",stdin); freopen("manout.txt","w",stdout); int i, s, e; scanf("%d%d",&n,&w); for(i = 1; i <= n; ++ i) { scanf("%d",&a[i]); a[i] += a[i-1]; } for(i = 1; i+w-1 <= n; ++ i) { s = i; e = i + w - 1; if(a[e] - a[s-1] > ans) ans = a[e] - a[s-1]; } printf("%d",ans); return 0; } |

## Invasion

As a highly-trained and razor-sharp military strategist, you have decided that it is time to establish your own empire. Unfortunately you do not have an army with which to do this: since the hushed-up incident with the pet hamster and the nuclear power plant, you were exiled from your former nation and nowadays you are on your own.

Your grand plan requires you to find a new nation to join forces with. You will then immediately invade all of its neighbours, taking them completely by surprise. Of course your empire will probably end there, since your forces will be so stretched at this point that you will not be able to expand any further.

The first decision for you to make is which nation to join forces with. You have acquired a map that shows the boundaries of the nations in your region. You wish to invade as many countries as possible, which means you must choose a nation with as many neighbours as possible.

Military maps are of course highly structured, and this map is no exception. It consists of a large grid of square cells, where each nation is formed from some group of cells. An example map on a 3 x 6 grid of cells is shown below, describing the nine nations `a`, `b`, ..., `i`.

Two nations are considered *neighbours* if they own land that is vertically or horizontally adjacent (for instance, `a` and `d` are neighbours in the example above, but `a` and `e` are not since they only touch at a corner).

Your task is to find the largest number of countries that you can invade, that is, the largest number of neighbours that any single nation has.

### Solution

枚举一个点，加入相邻不同色到该色点集中，直接统计即可

时间复杂度

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <bits/stdc++.h> using namespace std; #define pb push_back const int N = 1005; const int dx[] = {0,0,1,-1}; const int dy[] = {1,-1,0,0}; int n, m; char g[N][N]; vector<int> mp[27]; bool check(int x,int y){return x < 1 || y < 1 || x > n || y > m;} int main() { freopen("invin.txt","r",stdin); freopen("invout.txt","w",stdout); int i, j, k, nx, ny, ans = 0; scanf("%d%d",&n,&m); for(i = 1; i <= n; ++ i) scanf("%s",g[i]+1); for(i = 1; i <= n; ++ i) for(j = 1; j <= m; ++ j) for(k = 0; k < 4; ++ k) { nx = i + dx[k]; ny = j + dy[k]; if(!check(nx, ny) && g[i][j] != g[nx][ny]) mp[g[i][j]-'a'+1].pb(g[nx][ny]); } for(i = 1; i <= 26; ++ i) { sort(mp[i].begin(),mp[i].end()); ans = max(ans, unique(mp[i].begin(),mp[i].end())-(mp[i].begin())); } printf("%d",ans); return 0; } |

## Restaurants

You are the organiser for the Youth United Nations Conference which is being held this year in Le Nourse, Switzerland. It is the first night and you need to find somewhere for everybody to eat, but having forgotten to book, the local restaurants are nearly full and only have limited seating left.

Due to the important political nature of the Youth UN, it is crucial that no two delegates from the same country eat at the same restaurant. This will force them to meet the delegates from other countries and get to work on solving the world's problems.

However, because of the limited seating, this arrangement may not be possible--in particular, some delegates may not be able to eat at a restaurant. You would like to minimise the number of delegates that miss out so as not to cause an international incident.

Knowing that the fate of the world's future political leaders rests solely on your shoulders, you whip out your trusty laptop and set about determining the fewest number of delegates that will be forced to go hungry.

### Solution

xjb暴力一下就好了

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <bits/stdc++.h> using namespace std; const int N = 5005; int n, a[N], m, b[N], ans; bool cmp(int a,int b){return a > b;} int main() { freopen("restin.txt","r",stdin); freopen("restout.txt","w",stdout); int i, j, k; scanf("%d",&n); for(i = 1; i <= n; ++ i) scanf("%d",&a[i]); scanf("%d",&m); for(i = 1; i <= m; ++ i) scanf("%d",&b[i]); for(i = 1; i <= n; ++ i) { k = a[i]; for(j = 1; j <= m && k; ++ j) if(b[j] >= 1) -- b[j], -- k; ans += k; } printf("%d",ans); return 0; } |

## Air Drop

Election time is looming, and the battle for votes will be fierce. To win over the public's hearts and minds, the major parties are always looking for new and unusual methods of advertising, and this year they have hit upon a winner: the *air drop*.

In an air drop, the leader of the party flies over a city in an aeroplane and drops glossy leaflets onto the ground below. These leaflets fall in a straight line across the city, with the leaflets equally spaced along this line.

You are employed as the Grand Auditor, and it is your job to estimate just how much of the taxpayers' money is being spent on this exercise. Your first investigation takes you to the main street of the city, where you find eight leaflets littered along the street. These leaflets are found at positions 1, 3, 4, 7, 9, 10, 11 and 14 metres along the street as illustrated below.

Your task is to determine the *largest number of leaflets* that could have been dropped in a single flight. For instance, in the illustration above, a single flight could have dropped leaflets at positions 7, 9 and 11 metres along the street (since these three leaflets are equally spaced). Likewise, a single flight could have dropped leaflets at positions 3, 7 and 11 metres. However, the *largest* number of leaflets that could be dropped in a single flight is four, landing at positions 1, 4, 7 and 10 metres along the street.

With a frown you write a note in your little black book and move to the next street where there are even more leaflets to consider. As you watch the propaganda planes zooming overhead you realise you will be here for a long time yet; you therefore decide to write a computer program to help you with your task.

### Solution

设表示以为结尾，公差为的最长子序列的长度

根据决策值单调，很容易推出

但是暴力枚举公差实在是太慢了，时间复杂度为

考虑修改状态描述

设表示以为结尾，公差为的最长子序列长度

易推出

怎么求呢？我们做个变换，

于是直接二分就好了

注意特判的情况，时间复杂度为

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <bits/stdc++.h> using namespace std; const int N = 1005; int n, a[N], f[N][N], ans; int find(int L,int R,int x) { int mid, ret = 0; while(L <= R) { mid = L + R >> 1; if(a[mid] >= x) ret = mid, R = mid - 1; else L = mid + 1; } return ret; } int main() { freopen("dropin.txt","r",stdin); freopen("dropout.txt","w",stdout); int i, j, k; scanf("%d",&n); for(i = 1; i <= n; ++ i) scanf("%d",&a[i]); ans = 1; for(i = 2; i <= n; ++ i) for(j = i-1; j ; -- j) { f[i][j] = 2; k = find(1,j-1,2*a[j]-a[i]); if(k && a[j]-a[k] == a[i]-a[j]) f[i][j] = max(f[i][j], f[j][k] + 1); ans = max(ans,f[i][j]); } printf("%d",ans); return 0; } |