2006年ACM广东省赛

来源:互联网 发布:网络舆论战 编辑:程序博客网 时间:2024/04/25 01:03

Problem A Abundance

Description
An abundant number is a positive integer n for which Sigma(n) – 2n > 0, Where Sigma(n) is defined as the sum of all the divisors of n. And the quantity Sigma(n) – 2n is called abundance.

Given the range of n, you should find out the maximum abundance value that can be reached. For example, if the range is [10,12], then the only abundant number is 12, and the maximum abundance value is Sigma(12) – 2 * 12 = 4.

Input
Input may contain several test cases. The first line is a positive integer, T (T<=20), the number of test cases below. Each test case contains two positive integers x, y, (1<= x <= y <= 1024),indicating the range of n.

Output
For each test case, output the maximum abundance value that can be reached in the range of n. If there is no abundant number n in the given range, simply output -1.

Sample Input
3
1 1
10 12
1 1024

Sample Output
-1
4
1208
2

#include <cstdio>#include <cmath>#include <iostream>using namespace std;int t, x, y, sigma[1050];int main() {#ifndef ONLINE_JUDGE  freopen("in.txt", "r", stdin);#endif  for (int i = 1; i <= 1040; ++i) {    for (int j = i; j <= 1040; j += i) {      sigma[j] += i;    }  }  scanf("%d", &t);  while (t--) {    scanf("%d%d", &x, &y);    int ans = -1;    for (int i = x; i <= y; ++i) {      int temp = sigma[i] - 2*i;      if (temp > 0 && ans < temp) ans = temp;    }    printf("%d\n", ans);  }  return 0;}

Problem B Cover

Description

Tom wants to cover a rectangular floor by identical L-shape tiles without overlap.
这里写图片描述
As shown below, the floor can be split into many small squares, and the L-shape tile consists of exactly four small squares. The floor of 3*8 can be completely covered by6 L-shape tiles, but the floor of 3*7 is impossible.

Tom would like to know whether an arbitrary floor with n*m small squares can be completely covered or not. He is sure that when n and m are small he can find the answer by paper work, but when it comes to larger n and m, he has no idea to find the answer. Can you tell him?

Input
The input file will consist of several test cases. Each case consists of a single line with two positive integers m and n (1<=m<=15,1<=n<=40).
The input is ended by m=n=0.

Output
For each case, print the word ‘YES’ in a single line if it is possible to cover the m*n floor, print ‘NO’ otherwise.

Sample Inpu
3 8
3 7
0 0

Sample Output
YES
NO
3

#include <iostream>using namespace std;int main() {  int n, m;  while (scanf("%d%d", &n, &m), n != 0 || m != 0) {    printf("%s\n", n != 1 && m != 1 && n*m % 8 == 0 ? "YES" : "NO");  }  return 0;}

Problem D Spiral Description

Given an odd number n, we can arrange integers from 1 to n*n in the shape of a spiral.

The figure below illustrates the spiral made by integers from 1 to 25.

这里写图片描述

As we see above, each position in the spiral corresponds to a unique integer. For example, the number in row 1, column 1 is 21, and integer 16 is in row 5, column 2.

Now, given the odd number n (1<=n<=32768), and an integer m (1<=m<=n*n), you should write a program to find out the position of m.

Input
The first line of the input is a positive integer T(T<=20). T is the number of the test cases followed. Each case consists of two integer n and m as described above.

Output
For each case, output the row number and column number that the given integer is in, separated by a single whitespace. Please note that the row and column number are both starting from 1.

Sample Input
3
3 9
5 21
5 16

Sample Output
1 3
1 1
5 2
5

#include <cstdio>#include <cmath>#include <iostream>using namespace std;int t, n, num;void Solve(int &r, int &c) {  int cnt, k;  for (cnt = 1; ; cnt += 2) {    if (cnt*cnt == num) {      r = n / 2 - cnt / 2 + 1;      c = n / 2 + cnt / 2 + 1;      return;    } else if (cnt*cnt > num) {      r = n / 2 - cnt / 2 + 1;      c = n / 2 + cnt / 2 + 1;      break;    }  }  cnt *= cnt;  int k0 = cnt - 1;  k = k0;   while (k--) { --cnt; --c; if (num == cnt) return; }  k = k0;  while (k--) { --cnt; ++r; if (num == cnt) return; }  k = k0;  while (k--) { --cnt; ++c; if (num == cnt) return; }  k = k0 - 1;  while (k--) { --cnt; --r; if (num == cnt) return; }}int main() {#ifndef ONLINE_JUDGE  freopen("in.txt", "r", stdin);#endif  scanf("%d", &t);  while (t--) {    scanf("%d%d", &n, &num);    int x, y;    Solve(x, y);    printf("%d %d\n", x, y);  }  return 0;}

Problem F Flows in Grid

The maximum flow problem in general graph is so hard that bob doesn’t know how to solve it. So bob want to try an easy one, the maximum flow in grid. But this easier one is still too hard for bob. Now here is his problem, please help him:

Given you a N*M grid as followed, edges of the grid represent pipes which the water can run through; the number of the edge is the capacity of the pipe. For example the capacity of the edge between (0,0) and (1,0) is 6, it means that at most 6 units of
water can run through this edge(pipe).

这里写图片描述

So what is the maximum flow from S to T in the grid? In other words, at most how many units of water can run through from S to T at a time?

Input
The first line of the input is a positive integer T. T is the number of the test cases followed.

The first line of each test case is two positive integers N(1< N< 100) and M(1< M<100). And then two integer matrices H( N*(M-1) ) and V ( (N-1)*M )follow.

H[i][j] is the capacity of the edge between (i, j) and (i, j+1). V[i][j] is the capacity of the edge between (i, j) and (i+1, j). All integers in H and V are non-negative and smaller than 10^10.

Output
The output of each test case is an integer in one line, the maximum flow of the grid between S(0,0) and T(N-1,M-1). No redundant spaces are needed.

Sample Input
1
3 3
0 1
2 3
4 5
6 7 8
9 10 11
9

Sample Output
6
Hint
Here is one of the maximum flows of the example grid above:

这里写图片描述

ProblemG Hungry Cow

Description
Farmer John has longed for his journey toSan Antonio , not only to watch the Spurs playing against other NBA teams, but also to enjoy the ACM/ICPC world final.

However, there is still a problem: he has a little cow in his farm, and if he leaves his farm for long, then the cow may starve to death.

Fortunately, there is great grassland around Farmer John’s farm house (the farm house can be viewed as a segment). So Farmer John has decided to tie the cow on a pole in front of the farm house, so that the cow will be able to move around the pole to eat grass when he is away.

To simplify the situation, Farmer John will guarantee that the distance between the pole and each of the two endpoints of the farm house are the same. The figure below illustrates an example of the related positions of Farmer John’s farm house and the pole:

这里写图片描述
As Farmer John only finds a rope with limited length, he would like to know the area that the cow could eat grass, to make sure that the cow will keep alive during his journey.

It’s your task to write a program to help him. And please note that the cow can never pass through the area occupied by the farm house.

Input
Input may contain several test cases. The first line is an integer, T (T<=100), the number of test cases below. Each test case contains three positive integers: L, D, S, (L, D, S <= 10000), L is the length of the farm house segment (the length of segment E1E2in the figure above), D is the distance between the pole and the center of the
farm house (the distance between point Pole and point O in the figure above), and S is the length of the rope used to tie the cow. It’s guaranteed that S will never exceed L plus the distance between the pole and the end point E1.

Output
For each test case, output the area that the cow can reach to eat grass, round to 2 digits after the decimal point.

Sample Input
3
2 1 1
2 1 2
2 1 3

Sample Output
3.14
11.23
27.13
11

#include <cstdio>#include <cmath>#include <iostream>using namespace std;const double PI = 3.14159265358979323846;int main(){  int t;  double L, D, S, j1, j2, j3, j4, a0, a1, a2, a, s0, s1;  scanf("%d", &t);  while (t--) {    scanf("%lf%lf%lf", &L, &D, &S);    j1 = atan(L/2/D);    j2 = PI - j1;    j3 = PI/2 - j1;    j4 = PI - j3;    s1 = sqrt(L/2*L/2 + D*D);    s0 = S - s1;    if (S <= D) {      a = PI*S*S;    } else if (S > D && S <= s1){      double x = sqrt(S*S - D*D);      double ja = acos(D/S);      a1 = x*D;      a2 = PI*S*S*ja*2/(2*PI) - a1;      a = PI*S*S - a2;    } else if (s0 > L) {      a2 = PI*S*S*2*j2/(2*PI);      double j5 = j4 - acos(L/2/s0);      a0 = PI*s0*s0*j4*2/(2*PI);      double h = sqrt(s0*s0 - L/2*L/2);      a1 = L/2*h;      a = a0+a1+a2;    } else if (s0 > L/2) {      a2 = PI*S*S*2*j2/(2*PI);      a0 = 2*PI*s0*s0*j4/(2*PI);      a1 = L*D/2;      double h = sqrt(s0*s0 - L/2*L/2);      double aa = L/2*h/2;      double j6 = acos(L/2/s0);      double ab = PI*s0*s0*j6/(2*PI);      ab -= aa;      a = a0+a1+a2-2*ab;    } else {      a2 = PI*S*S*2*j2/(2*PI);      a0 = 2*PI*s0*s0*j4/(2*PI);      a1 = L*D/2;      a = a0+a1+a2;    }    printf("%.2f\n", a);  }    return 0;}

Problem I Ping

Description
When the network runs into trouble, we often use the command “ping” to test whether the computer is well connected to others.

For example, if we want to test whether our computer is well connected to the host of Zhongshan University, we would use the command “pingwww.zsu.edu.cn”. Then if the network works well, we would get some replies such as:

Reply from 202.116.64.9: bytes=32 time=1ms TTL=126
Reply from 202.116.64.9: bytes=32 time<1ms TTL=126

But how can we get a reply with the whole information above, especially the time used? As follows are some details about the “Ping” process, and please note that this explanation is for this problem only and may be different from the actual “Ping”command:

First of all, there are two kinds of message related to this “Ping” process, the echo request and echo reply.

The echo request message contains a TimeElapsed field to record the time used since it’s sent out from the source. We can assume that in the network, each host (router, switcher, computer, and so on) is so “polite” that if the incoming message does not aim to itself, then it will update the TimeElapsed field in the message with the time used to transfer the message from the direct sender to itself, and send the message to all the other hosts that is connected to them directly. So after we send out an echo request packet, the network can “automatically” transfer it to the target host.

Once the target host receives an echo request message, it replies with an echo reply message. The echo reply message also contains a TimeElapsed field, which is filled by the target host using the TimeElapsed field in the echo request message, and will not be changed by those intermediate computers. Then the network “automatically” transfers the reply to us again. That’s why we know whether the network is well connected or not, and the shortest time it takes to transfer a message from our
computer to the target host.

Actually, there is still one problem with the “Ping” process above. Suppose intermediate computers A and B are directly connected to each other, and a message aiming to C reaches A, then A will transfer the message to B since A is “polite”, and
then B will send the message back to A again since B is “polite” too, then A and B are trapped into an infinite loop and keep on sending message to each other. To solve this problem, a host would throw away an incoming message if the message has been
transferred for more than ten hops (Each time a host A sends a message to another host B is called one hop).

The problem is, given the details of the network, what is the reply time we will get. Please note that this reply time will equal to the shortest time to transfer a message from the source to the target host if possible.

Input
The input will contain multiple test cases. In each test case, the first line is three integers n (n<=1000), m and t (0<=t < n), n is the number of hosts in the network (including our computer), m is the number of pairs of directly connected computers, and t is the target host that we would like to ping. (We always assume our computer to be host 0).

Then there are m lines followed, each of which has three integers a (0<=a< n), b (0<=b< n) and c (0< c<=1000), indicating that host a is directly connected to b, and the time required to transfer a message from a to b or vice versa is equal to c.

The input will be terminated by a case with n=0, which should not be processed.

Output
For each case, if our computer can get the reply from the target computer, print the reply time in one line. Otherwise print “no”.

Sample Input
3 2 2
0 1 2
1 2 3
3 1 2
0 1 2
0 0 0

Sample Output
5
no

#include <cstdio>#include <vector>#include <queue>#include <cstring>using namespace std;const int SIZE = 1000 + 10;class Edge {public:  int to, time;  Edge(int a, int b) {    to = a; time = b;  }};class Node {public:  int cur, cost, times;  Node(int a, int b, int c) {    cur = a; cost = b; times = c;  }  bool operator < (const Node &a) const {    return cost > a.cost;  }};int n, m, t, dpcost[SIZE];vector<Edge> vec[SIZE];void Init() {  memset(dpcost, 0x3f, sizeof(dpcost));  dpcost[0] = 0;  for (int i = 0; i < SIZE; ++i) {    vec[i].clear();  }}void Bfs() {  priority_queue<Node> que;  que.push(Node(0, 0, 0));  while (!que.empty()) {    Node head = que.top(); que.pop();    if (head.cur == t) {      printf("%d\n", head.cost);      return;    }    for (int i = 0; i < vec[head.cur].size(); ++i) {      int to = vec[head.cur][i].to;      int time = vec[head.cur][i].time;      if (head.times < 10 && dpcost[to] > head.cost + time) {        dpcost[to] = head.cost + time;        que.push(Node(to, dpcost[to], head.times + 1));      }    }  }  printf("no\n");}int main() {  while (scanf("%d%d%d", &n, &m, &t), n != 0) {    Init();    for (int i = 0; i < m; ++i) {      int a, b, c;      scanf("%d%d%d", &a, &b, &c);      vec[a].push_back(Edge(b, c));      vec[b].push_back(Edge(a, c));    }    Bfs();  }    return 0;}
0 0