首页 > ACM题库 > HDU-杭电 > Hdu 1101 The Parallel Challenge Ballgame-最小生成树[解题报告] C++
2013
11-28

Hdu 1101 The Parallel Challenge Ballgame-最小生成树[解题报告] C++

The Parallel Challenge Ballgame

问题描述 :

Before the ACM/ICPC world final 2005, there is a competition called “The Parallel Challenge Ballgame”. The Parallel Challenge ballgame gives each team a chance to pit their programming skills against those of other teams in a fast-moving parallel-programming game of skill, treachery, and hazard avoidance. Each team will write a single C++ class named MyPlayer which defines the characteristics of a “player”. The MyPlayer class will be instantiated five times in the environment, making up a five-player team, which will then compete in a series of Parallel Challenge ballgames running on an IBM Power Architecture Blue Gene supercomputer � the world’s fastest computer.A Parallel Challenge ballgame is played on a rectangular filed. The filed is surrounded by a wall; balls will bounce off the walls if they run into it. The rule of bouncing is the same as light (In figure 1,angle 1 equals angle 2). Near the edges of the fields are a number of goals where points can be scored. Goals are rectangular areas lying near the edges of the field but within the field boundaries. When the game starts there are a number of balls placed at random locations on the field. A player can move to a ball, pick it up, and throw (of course, it is not football, why not use hand?) it. At the start of each game there are also a number of “nets” distributed at various locations on the edges of the field. A player can move to and pick up one of these nets, and can then use them to “trap” players on other teams by throwing the net on top of them. Once a player is trapped beneath a net, that player cannot do anything more in the game until a teammate comes and lifts the net from the trapped player. A player may “tackle” another player, normally in an attempt to dislodge a ball being carried by the other player (although it is also legal to tackle a player who is not carrying a ball).

The objective of each team is to write their MyPlayer class so that their players (the five instances of the class) operate in a coordinated fashion, taking advantage of the various ways to score points while at the same time avoiding both hazards on the game filed and impediments thrown at them by players from other teams. The winner of a game is the team whose players score the largest total number of points.
There are many ways to score points:
(1)  Successful Tackle (tackle not caught by Referees)
(2)  Opponent’s Failed Tackle
(3)  Throwing a net on one or more opponents
(4)  Lifting a net off a teammate
And of course, the normal approach: (5) Carry or throw the balls into goals. This is also the easiest way to score points. In order to get more chance to make a ball into the goal, it is better to throw a ball to a goal once you get it. The ball may be blocked by other player, but the probability is low, because a thrown ball moves at the maximum speed allowed in the game, and the player can not catch up with it. So the only way it is blocked is that some player is just on the direction, which the ball moves. And because the ball will bounce off the wall when it hits the wall, it is not necessary to throw a ball straight to a goal (see figure 2). But the more times the ball bounces off the wall, the higher probability that other player will head off it. So we only consider the ball bounces off the wall no more than once.

Here is our problem. Given the range of the field, the position of the ball and the goals, the size of the goals, your task is to calculate how many percents of the direction that the team can score points through method (5).

输入:

In the first line of input, there is an integer t, which is the number of test cases and followed by the data for the test cases. The first line of each test case contains four integers: x1, y1, x2, y2, and (x1, y1) and (x2, y2) (-1000 <= x1, y1, x2, y2 <= 1000) are the coordinates of the diagonally points of the field. In the next line, there are two integers x and y, and (x, y) is the coordinate of the ball. The third line of each test case contains an integer n (0 <= n <= 100), which is the number of the goals. In next n lines, each line contains four integers: xi1, yi1, xi2, yi2, and (xi1, yi1) and (xi2, yi2) are the coordinates of the diagonally points of the i-th goal. You may assume the goals and the ball are inside the field. And if a ball move into or on the boundaries of a goal, the team scores points.

输出:

The output contains one line per test case containing a number, which is described above and followed a “%”. The number should be rounded up to two decimal digits. See the Sample Output to know the exact format.

样例输入:

1
100 100 -100 -100 
0 0
1
10 10 -10 20

样例输出:

28.34%

 

把已存在的边的长度赋为0,就是赤裸裸的最小生成树!

prim就是每次算出一条最短边,再找出一个点离树最近!这也是与dijkstra算法的区别之处!一个是离树最近,一个

是离出发点最近!其他的差不多~

下面的是prim算法!

#include<stdio.h>
#include<string.h>
#define MAX 1002
#define max 99999
int map[MAX][MAX],used[MAX],f[MAX];
int main()
{
int n,i,j,k,m,a,b,min,sum;
while(scanf("%d",&n)!=EOF)
{
memset(used,0,sizeof(used));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&map[i][j]);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
   scanf("%d %d",&a,&b);
   map[a][b]=map[b][a]=0;
}
for(i=1;i<=n;i++)
f[i]=map[1][i];
f[1]=0;sum=0;
for(i=1;i<=n;i++)
{
   min=max;
   for(j=1;j<=n;j++)
   if(!used[j]&&f[j]<min)
   {min=f[j];k=j;}
   if(min==max)break;
   used[k]=1;
   sum+=f[k];
   for(j=1;j<=n;j++)
   if(!used[j]&&f[j]>map[k][j]) (离树最近)
   f[j]=map[k][j];
}
printf("%d\n",sum);
}
}
in=max;
   for(j=1;j<=n;j++)
   if(!used[j]&&f[j]<min)
   {min=f[j];k=j;}
   if(min==max)break;
   used[k]=1;
   sum+=f[k];
   for(j=1;j<=n;j++)
   if(!used[j]&&f[j]>map[k][j]) (离树最近)
   f[j]=map[k][j];
}
printf("%d\n",sum);
}
}

 


  1. 第二种想法,我想来好久,为啥需要一个newhead,发现是把最后一个节点一直返回到嘴上面这层函数。厉害,这道题之前没样子想过。

  2. 我没看懂题目
    2
    5 6 -1 5 4 -7
    7 0 6 -1 1 -6 7 -5
    我觉得第一个应该是5 6 -1 5 4 输出是19 5 4
    第二个是7 0 6 -1 1 -6 7输出是14 7 7
    不知道题目例子是怎么得出来的