前几天打了一场外国人的比赛,感觉那边的题目质量还是很好的,区分度很鲜明,题目没有国内的难,坑点比较少,比较注重思维,基础算法。
B题:
As the name of the event implies, such a sprint relay consist of 4 legs, 100 meters each. One would think that the best team would simply consist of the 4 fastest 100 m runners in the nation, but there is an important detail to take into account: flying start. In the 2 nd, 3 rd and 4 th leg, the runner is already running when the baton is handed over. This means that some runners – those that have a slow acceleration phase – can perform relatively better in a relay if they are on the 2 nd, 3 rd or 4 th leg.
You have a pool of runners to choose from. Given how fast each runner in the pool is, decide which four runners should represent your national team and which leg they should run. You are given two times for each runner – the time the runner would run the 1 st leg, and the time the runner would run any of the other legs. A runner in a team can only run one leg.
The first line of input contains an integer n , the number of runners to choose from ( 4≤n≤500 ). Then follow n lines describing the runners. The i ’th of these lines contains the name of the i ’th runner, the time ai for the runner to run the 1 st leg, and the time bi for the runner to run any of the other legs ( 8≤bi≤ai<20 ). The names consist of between 2 and 20 (inclusive) uppercase letters ‘A’-‘Z’, and no two runners have the same name. The times are given in seconds with exactly two digits after the decimal point.
First, output a line containing the time of the best team, accurate to an absolute or relative error of at most 10−9 . Then output four lines containing the names of the runners in that team. The first of these lines should contain the runner you have picked for the 1 st leg, the second line the runner you have picked for the 2 nd leg, and so on. Any solution that results in the fastest team is acceptable.
Sample Input 1 | Sample Output 1 |
---|---|
6 ASHMEADE 9.90 8.85 BLAKE 9.69 8.72 BOLT 9.58 8.43 CARTER 9.78 8.93 FRATER 9.88 8.92 POWELL 9.72 8.61 |
35.54 CARTER BOLT POWELL BLAKE |
Sample Input 2 | Sample Output 2 |
---|---|
9 AUSTRIN 15.60 14.92 DRANGE 15.14 14.19 DREGI 15.00 14.99 LAAKSONEN 16.39 14.97 LUNDSTROM 15.83 15.35 MARDELL 13.36 13.20 POLACEK 13.05 12.55 SANNEMO 15.23 14.74 SODERMAN 13.99 12.57 |
52.670000 MARDELL POLACEK SODERMAN DRANGE |
#include
using namespace std;
const int maxn = 500 + 10;
int n;
double eps = 0.0000000001;
struct node{
string name;
double speed1, speed2;
bool operator <(const node &res) const{
return speed2 < res.speed2;
}
}Node[maxn];
vector g;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
cin>>Node[i].name>>Node[i].speed1>>Node[i].speed2;
}
double Min = 1000000000000.0;
string s1, s2, s3, s4;
for(int i = 1; i <= n; i++)
{
g.clear();
double sum = Node[i].speed1;
for(int j = 1; j <= n; j++)
{
if(j != i) g.push_back(Node[j]);
}
sort(g.begin(), g.end());
for(int j = 0; j <= 2; j++)
{
sum += g[j].speed2;
}
if(sum - Min < eps)
{
Min = sum;
s1 = Node[i].name;
s2 = g[0].name;
s3 = g[1].name;
s4 = g[2].name;
}
}
printf("%.2lf\n", Min);
cout<
The similarity between two characters A and B is calculated as follows: for each feature f , if both A and B have feature f or if none of them have feature f , the similarity increases by one.
Tira does not have a character yet. She would like to create a new, very original character so that the maximum similarity between Tira’s character and any other character is as low as possible.
Given the characters of the other players, your task is to create a character for Tira that fulfils the above requirement. If there are many possible characters, you can choose any of them.
The first line of input contains two integers n and k , where 1≤n≤105 is the number of players (excluding Tira) and 1≤k≤20 is the number of features.
Then follow n lines describing the existing characters. Each of these n lines contains a string of k digits which are either 0 or 1 . A 1 in position j means the character has the j ’th feature, and a 0 means that it does not have the j ’th feature.
Output a single line describing the features of Tira’s character in the same format as in the input. If there are multiple possible characters with the same smallest maximum similarity, any one of them will be accepted.
Sample Input 1 | Sample Output 1 |
---|---|
3 5 01001 11100 10111 |
00010 |
Sample Input 2 | Sample Output 2 |
---|---|
1 4 0000 |
1111 |
#include
using namespace std;
const int maxn = 1000000 + 200000;
int inf = 0x3f3f3f3f;
int n, tot, k;
int head[maxn];
bool visit[maxn];
char ch[30];
int digit[30];
int dis[maxn];
int sum;
struct edge{
int v, w, Nxt;
}Edge[maxn<<5];
vector g;
void init()
{
tot = 0;
memset(head, -1, sizeof(head));
memset(visit, false, sizeof(visit));
g.clear();
}
int Transform(char *s)
{
int ans = 0;
int len = strlen(s);
for(int i = 0; i < len; i++)
{
if(s[i] == '1') ans += (1<>i)&1;
}
for(int i = 0; i < k; i++)
{
int x = 0;
for(int j = 0; j < k; j++)
{
int value;
if(i == j) value = digit[j]^1;
else value = digit[j];
if(value) x += (1< res.w;
}
};
void bfs()
{
memset(dis, inf, sizeof(dis));
priority_queue q;
while(!q.empty()) q.pop();
q.push(node(sum, 0));
dis[sum] = 0;
while(!q.empty())
{
node nx = q.top();
q.pop();
int u = nx.u;
int w = nx.w;
if(dis[u] < w) continue;
for(int i = head[u]; i != -1; i = Edge[i].Nxt)
{
int v = Edge[i].v;
int ww = Edge[i].w;
if(dis[v] > dis[u] + ww)
{
dis[v] = dis[u] + ww;
q.push(node(v, dis[v]));
}
}
}
}
int main()
{
init();
scanf("%d%d", &n, &k);
int judge = 0;
for(int i = 1; i <= n; i++)
{
scanf("%s", ch);
int num = Transform(ch);
if(!visit[num])
{
visit[num] = true;
g.push_back(num);
judge++;
}
}
sum = (1<= sum)
{
for(int i = 1; i <= k; i++)
{
cout<<"0";
}
cout< Max)
{
Max = dis[i];
st = i;
}
}
for(int i = 0; i < k; i++)
{
int value = (st>>i)&1;
cout<
E题:
First, Gunnar wants to build a floodbank connecting Denmark and Norway to separate the Baltic from the Atlantic Ocean. The floodbank will also help protect Nordic countries from rising sea levels in the ocean. Next, Gunnar installs a device that can drain the Baltic from the seafloor. The device will drain as much water as needed to the Earth’s core where it will disappear forever (because that is how physics works, at least as far as Gunnar is concerned). However, depending on the placement of the device, the entire Baltic might not be completely drained – some pockets of water may remain.
To simplify the problem, Gunnar is approximating the map of the Baltic using a 2 -dimensional grid with 1 meter squares. For each square on the grid, he computes the average altitude. Squares with negative altitude are covered by water, squares with non-negative altitude are dry. Altitude is given in meters above the sea level, so the sea level has altitude of exactly 0 . He disregards lakes and dry land below the sea level, as these would not change the estimate much anyway.
Water from a square on the grid can flow to any of its 8 neighbours, even if the two squares only share a corner. The map is surrounded by dry land, so water never flows outside of the map. Water respects gravity, so it can only flow closer to the Earth’s core – either via the drainage device or to a neighbouring square with a lower water level.
Gunnar is more of an idea person than a programmer, so he has asked for your help to evaluate how much water would be drained for a given placement of the device.
The first line contains two integers h and w , 1≤h,w≤500 , denoting the height and width of the map.
Then follow h lines, each containing w integers. The first line represents the northernmost row of Gunnar’s map. Each integer represents the altitude of a square on the map grid. The altitude is given in meters and it is at least −106 and at most 106 .
The last line contains two integers i and j , 1≤i≤h,1≤j≤w , indicating that the draining device is placed in the cell corresponding to the j ’th column of the i ’th row. You may assume that position (i,j) has negative altitude (i.e., the draining device is not placed on land).
Output one line with one integer – the total volume of sea water drained, in cubic meters.
Sample Input 1 | Sample Output 1 |
---|---|
3 3 -5 2 -5 -1 -2 -1 5 4 -5 2 2 |
10 |
Sample Input 2 | Sample Output 2 |
---|---|
2 3 -2 -3 -4 -3 -2 -3 2 1 |
16 |
#include
using namespace std;
typedef long long LL;
const int maxn = 510;
int h, w, s, t;
LL M[maxn][maxn];
LL Level[maxn][maxn];
LL dis[maxn][maxn];
int dx[4] = {0, 1, -1};
int dy[4] = {0, 1, -1};
LL up;
bool visit[maxn][maxn];
bool judge(int xx, int yy)
{
if(xx < 1 || xx > h) return false;
if(yy < 1 || yy > w) return false;
return true;
}
struct node{
int x, y;
LL d;
node(){}
node(int _x, int _y, LL _d){
x = _x;
y = _y;
d = _d;
}
bool operator <(const node &res) const {
return d < res.d;
}
};
LL ans;
void solve()
{
priority_queue q;
while(!q.empty()) q.pop();
q.push(node(s, t, -M[s][t]));
dis[s][t] = -M[s][t];
up = -M[s][t];
while(!q.empty())
{
node nx = q.top();
q.pop();
int x = nx.x;
int y = nx.y;
LL d = nx.d;
if(dis[x][y] > d) continue;
for(int i = 0; i <= 2; i++)
{
for(int j = 0; j <= 2; j++)
{
if(i == j && i == 0) continue;
int nowx = x + dx[i];
int nowy = y + dy[j];
if(!judge(nowx, nowy)) continue;
if(M[nowx][nowy] >= 0) continue;
LL Max = min(dis[x][y], abs(M[nowx][nowy]));
Max = min(Max, up);
if(dis[nowx][nowy] < Max)
{
dis[nowx][nowy] = Max;
q.push(node(nowx, nowy, Max));
}
}
}
}
}
int main()
{
scanf("%d%d", &h, &w);
for(int i = 1; i <= h; i++)
{
for(int j = 1; j <= w; j++)
{
scanf("%lld", &M[i][j]);
}
}
scanf("%d%d", &s, &t);
memset(visit, false, sizeof(visit));
memset(dis, 0, sizeof(dis));
ans = 0;
solve();
for(int i = 1; i <= h; i++)
{
for(int j = 1; j <= w; j++)
{
ans += dis[i][j];
}
}
printf("%lld\n", ans);
return 0;
}
This year there are n teams in the contest. The teams are numbered 1,2,…,n , and your favorite team has number 1 .
Like today, the score of a team is a pair of integers (a,b) where a is the number of solved problems and b is the total penalty of that team. When a team solves a problem there is some associated penalty (not necessarily calculated in the same way as in the NCPC – the precise details are not important in this problem). The total penalty of a team is the sum of the penalties for the solved problems of the team.
Consider two teams t1 and t2 whose scores are (a1,b1) and (a2,b2) . The score of team t1 is better than that of t2 if either a1>a2 , or if a1=a2 and b1<b2 . The rank of a team is k+1 where k is the number of teams whose score is better.
You would like to follow the performance of your favorite team. Unfortunately, the organizers of GCPC do not provide a scoreboard. Instead, they send a message immediately whenever a team solves a problem.
The first line of input contains two integers n and m , where 1≤n≤105 is the number of teams, and 1≤m≤105 is the number of events.
Then follow m lines that describe the events. Each line contains two integers t and p ( 1≤t≤n and 1≤p≤1000 ), meaning that team t has solved a problem with penalty p . The events are ordered by the time when they happen.
Output m lines. On the i ’th line, output the rank of your favorite team after the first i events have happened.
Sample Input 1 | Sample Output 1 |
---|---|
3 4 2 7 3 5 1 6 1 9 |
2 3 2 1 |
#include
using namespace std;
typedef long long LL;
const int maxn = 100000 + 10;
int n, m;
LL inf = -(1e8 + 1);
LL H[maxn * 2];
int Tree[maxn<<1];
int cnt;
int lowbit(int x)
{
return x&(-x);
}
void add(int loc, int value)
{
for(int i = loc; i <= cnt; i += lowbit(i))
{
Tree[i] += value;
}
}
int get(int loc)
{
int ans = 0;
for(int i = loc; i >= 1; i -= lowbit(i))
{
ans += Tree[i];
}
return ans;
}
int Hash(LL value)
{
return lower_bound(H, H + cnt, value) - H + 1;
}
void init()
{
sort(H, H + cnt);
cnt = unique(H, H + cnt) - H;
memset(Tree, 0, sizeof(Tree));
}
struct node{
int team, t;
}Node[maxn];
LL Time[maxn];
int main()
{
scanf("%d%d", &n, &m);
memset(Time, 0, sizeof(Time));
cnt = 0;
for(int i = 1; i <= m; i++)
{
scanf("%d%d", &Node[i].team, &Node[i].t);
int team = Node[i].team;
int tt = Node[i].t;
Time[team] += (inf + tt);
H[cnt++] = Time[team];
}
init();
memset(Time, 0, sizeof(Time));
for(int i = 1; i <= m; i++)
{
int team = Node[i].team;
int tt = Node[i].t;
int before = Hash(Time[team]);
add(before, -1);
Time[team] += (inf + tt);
int now = Hash(Time[team]);
add(now, 1);
int loc = Hash(Time[1]);
printf("%d\n", get(loc - 1) + 1);
}
return 0;
}
补上这题集合的代码:
#include
using namespace std;
const int maxn = 100000 + 10;
int n, m;
int p[maxn], t[maxn];
struct team{
int pp, tt;
team(){};
team(int _pp, int _tt){
pp = _pp;
tt = _tt;
}
bool operator <(const team &res) const{
if(pp == res.pp) return tt > res.tt;
else return pp < res.pp;
}
bool operator ==(const team &res) const{
return (pp == res.pp && tt == res.tt);
}
};
multiset s;
multiset::iterator it;
int main()
{
scanf("%d%d", &n, &m);
s.clear();
memset(p, 0, sizeof(p));
memset(t, 0, sizeof(t));
int id, value;
for(int i = 1; i <= m; i++)
{
scanf("%d%d", &id, &value);
if(id == 1)
{
p[1]++;
t[1] += value;
team n1 = team(p[1], t[1]);
while(!s.empty())
{
it = s.begin();
team nx = *it;
if(nx < n1 || nx == n1) s.erase(it);
else break;
}
}
else
{
int p1 = p[id] + 1;
int t1 = t[id] + value;
team n1 = team(p1, t1);
team n2 = team(p[1], t[1]);
if(n2 < n1)
{
it = s.find(team(p[id], t[id]));
if(it != s.end()) s.erase(it);
p[id]++;
t[id] += value;
s.insert(team(p[id], t[id]));
}
else
{
p[id]++;
t[id] += value;
}
}
printf("%d\n", s.size() + 1);
}
return 0;
}
As you sit down and think, you decide that the first thing to do is to eliminate the cycles in the dependency graph. So you start by finding a shortest dependency cycle.
The first line of input contains a number n , 1≤n≤500 , the number of files. Then follows one line with n distinct names of files. Each name is a string with at least 1 and at most 8 lower case letters ‘a’ to ‘z’. Then follow n sections, one section per file name, in the order they were given on the second line. Each section starts with one line containing the name of the file and an integer k , followed by k lines, each starting with “import”.
Each “import” line is a comma-space separated line of dependencies. No file imports the same file more than once, and every file imported is listed in the second line of the input. Comma-space separated means that every line will start with “import”, then have a list of file names separated by “, ” (see sample inputs for examples). Each import statement is followed by at least one file name.
If the code base has no cyclic dependencies, output “SHIP IT”. Otherwise, output a line containing the names of files in a shortest cycle, in the order of the cycle (i.e., the i th file listed must import the (i+1) st file listed, and the last file listed must import the first). If there are many shortest cycles, any one will be accepted.
Sample Input 1 | Sample Output 1 |
---|---|
4 a b c d a 1 import d, b, c b 2 import d import c c 1 import c d 0 |
c |
Sample Input 2 | Sample Output 2 |
---|---|
5 classa classb myfilec execd libe classa 2 import classb import myfilec, libe classb 1 import execd myfilec 1 import libe execd 1 import libe libe 0 |
SHIP IT |
Sample Input 3 | Sample Output 3 |
---|---|
5 classa classb myfilec execd libe classa 2 import classb import myfilec, libe classb 1 import execd myfilec 1 import libe execd 1 import libe, classa libe 0 |
#include
using namespace std;
const int maxn = 500 + 10;
int n;
map mp;
map mmpp;
vector g[maxn];
bool visit[maxn];
char ch[1000000];
char test[1000000];
struct node{
int v, depth;
node(){}
node(int _v = 0, int _depth = 0){
v = _v;
depth = _depth;
}
};
int pre[maxn];
vector ans;
int bfs(int s)
{
queue q;
while(!q.empty()) q.pop();
memset(visit, false, sizeof(visit));
memset(pre, -1, sizeof(pre));
q.push(node(s, 0));
visit[s] = true;
while(!q.empty())
{
node nx = q.front();
q.pop();
int u = nx.v;
int depth = nx.depth;
for(int i = 0; i < g[u].size(); i++)
{
if(g[u][i] == s)
{
pre[s] = u;
return depth;
}
int v = g[u][i];
if(!visit[v])
{
visit[v] = true;
pre[v] = u;
q.push(node(v, depth + 1));
}
}
}
return -1;
}
void debug()
{
for(int i = 1; i <= n; i++)
{
cout<<"i == "<>s;
mp[s] = i;
mmpp[i] = s;
//cout<<"s == "<>s>>num;
int id = mp[s];
//cout<<"num == "<= 0; i--)
{
if(i == 0) cout<
The point system works like this: If the number of tines on the left side and the right side match, the moose is said to have the even sum of the number of points. So, “an even 6 -point moose”, would have three tines on each side. If the moose has a different number of tines on the left and right side, the moose is said to have twice the highest number of tines, but it is odd. So “an odd 10 -point moose” would have 5 tines on one side, and 4 or less tines on the other side.
Can you figure out how many points a moose has, given the number of tines on the left and right side?
The input contains a single line with two integers ℓ and r , where 0≤ℓ≤20 is the number of tines on the left, and 0≤r≤20 is the number of tines on the right.
Output a single line describing the moose. For even pointed moose, output “Even x ” where x is the points of the moose. For odd pointed moose, output “Odd x ” where x is the points of the moose. If the moose has no tines, output “Not a moose”
Sample Input 1 | Sample Output 1 |
---|---|
2 3 |
Odd 6 |
Sample Input 2 | Sample Output 2 |
---|---|
3 3 |
Even 6 |
Sample Input 3 | Sample Output 3 |
---|---|
0 0 |
Not a moose |
#include
using namespace std;
int main()
{
int l,r;
while(~scanf("%d%d",&l,&r))
{
if(l==r&&(l||r))
{
cout<<"Even "<
The kayaks are of different types and have different amounts of packing, so some are more easily paddled than others. This is captured by a speed factor c that you have already figured out for each kayak. The final speed v of a kayak, however, is also determined by the strengths s1 and s2 of the two people in the kayak, by the relation v=c(s1+s2) . In your group you have some beginners with a kayaking strength of sb , a number of normal participants with strength sn and some quite experienced strong kayakers with strength se .
The first line of input contains three non-negative integers b , n , and e , denoting the number of beginners, normal participants, and experienced kayakers, respectively. The total number of participants, b+n+e , will be even, at least 2 , and no more than 100000 . This is followed by a line with three integers sb , sn , and se , giving the strengths of the corresponding participants ( 1≤sb<sn<se≤1000 ). The third and final line contains m=b+n+e2 integers c1,…,cm ( 1≤ci≤100000 for each i ), each giving the speed factor of one kayak.
Output a single integer, the maximum speed that the slowest kayak can get by distributing the participants two in each kayak.
Sample Input 1 | Sample Output 1 |
---|---|
3 1 0 40 60 90 18 20 |
1600 |
Sample Input 2 | Sample Output 2 |
---|---|
7 0 7 5 10 500 1 1 1 1 1 1 1 |
505 |
#include
using namespace std;
typedef long long LL;
const int maxn = 1000000 + 10;
int b, n, e;
int sb, sn, se;
int m;
int value[maxn];
double eps = 1e-7;
struct node{
int numb, numn, nume;
int sum;
bool operator <(const node &res) const{
return sum < res.sum;
}
}Node[maxn];
bool judge(int x)
{
int bb = b;
int nn = n;
int ee = e;
for(int i = 1; i <= m; i++)
{
double down = (double)x / (double)value[i];
int cnt = 0;
if(bb >= 2)
{
Node[cnt].numb = 2;
Node[cnt].numn = 0;
Node[cnt].nume = 0;
Node[cnt++].sum = sb + sb;
}
if(nn >= 2)
{
Node[cnt].numb = 0;
Node[cnt].numn = 2;
Node[cnt].nume = 0;
Node[cnt++].sum = sn + sn;
}
if(ee >= 2)
{
Node[cnt].numb = 0;
Node[cnt].numn = 0;
Node[cnt].nume = 2;
Node[cnt++].sum = se + se;
}
if(bb && nn)
{
Node[cnt].numb = 1;
Node[cnt].numn = 1;
Node[cnt].nume = 0;
Node[cnt++].sum = sb + sn;
}
if(bb && ee)
{
Node[cnt].numb = 1;
Node[cnt].numn = 0;
Node[cnt].nume = 1;
Node[cnt++].sum = sb + se;
}
if(nn && ee)
{
Node[cnt].numb = 0;
Node[cnt].numn = 1;
Node[cnt].nume = 1;
Node[cnt++].sum = sn + se;
}
sort(Node, Node + cnt);
int flag = false;
for(int j = 0; j < cnt; j++)
{
if(down - (double)Node[j].sum <= eps)
{
flag = true;
bb -= Node[j].numb;
nn -= Node[j].numn;
ee -= Node[j].nume;
break;
}
}
if(!flag) return false;
}
return true;
}
int main()
{
scanf("%d%d%d", &b, &n, &e);
m = (b + n + e) / 2;
scanf("%d%d%d", &sb, &sn, &se);
for(int i = 1; i <= m; i++)
{
scanf("%d", &value[i]);
}
int l = 0, r = 1000000000;
int re = -1;
while(l <= r)
{
int mid = (l + r)>>1;
if(judge(mid))
{
re = mid;
l = mid + 1;
}
else r = mid - 1;
}
printf("%d\n", re);
return 0;
}