codechef The Lead Game 题解

The game of billiards involves two players knocking 3 balls around
on a green baize table. Well, there is more to it, but for our
purposes this is sufficient.

The game consists of several rounds and in each round both players
obtain a score, based on how well they played. Once all the rounds
have been played, the total score of each player is determined by
adding up the scores in all the rounds and the player with the higher
total score is declared the winner.

The Siruseri Sports Club organises an annual billiards game where
the top two players of Siruseri play against each other. The Manager
of Siruseri Sports Club decided to add his own twist to the game by
changing the rules for determining the winner. In his version, at the
end of each round the leader and her current lead are calculated. Once
all the rounds are over the player who had the maximum lead at the
end of any round in the game is declared the winner.

Consider the following score sheet for a game with 5 rounds:

    Round     Player 1       Player 2

      1             140                 82
      2              89                 134 
      3              90                 110 
      4              112              106
      5              88                  90 

The total scores of both players, the leader and the lead after
each round for this game is given below:

    Round      Player 1       Player 2     Leader     Lead

      1               140           	 82        Player 1     58
      2               229           	216       Player 1     13
      3               319           	326       Player 2      7
      4               431           	432       Player 2      1
      5               519           	522       Player 2      3

The winner of this game is Player 1 as he had the maximum lead (58
at the end of round 1) during the game.


根据规则计算最后的胜者是谁:当前局结束时候领先分数最多者胜。

本题依然是输入数据十分大。算法不难,处理好输入数据就行。都是使用fread和getchar比较稳妥了。

#include <stdio.h>

int TheLeadGame()
{
	int T, n, lead = 0, leader, a = 0, b = 0, c = 0, d = 0;
	scanf("%d\n", &T);
	char buffer[100000];
	bool one = true;
	if ((n = fread(buffer, 1, 100000, stdin)) > 0)
	{
		for (int i = 0; i < n; i++)
		{
			if (one && buffer[i] != ' ' && buffer[i] != '\n') 
				a = a * 10 + buffer[i] - '0';
			else if (buffer[i] != ' ' && buffer[i] != '\n')
				b = b * 10 + buffer[i] - '0';

			if (buffer[i] == ' ') one = false;
			else if (buffer[i] == '\n' || i + 1 == n)
			{
				one = true;
				c += a;//player1 total scores
				a = 0;//reset
				d += b;//player2 total scores 
				b = 0;//reset

				if (c < d)//calculate
				{
					if ( d - c > lead )
					{
						lead = d - c;
						leader = 2;
					}
				}
				else
				{
					if ( c - d > lead )
					{
						lead =  c - d;
						leader = 1;
					}
				}
			}			
		}
	}
	printf("%d %d\n", leader, lead);
	return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
06-01
这道题是一道典型的费用限制最短路题目,可以使用 Dijkstra 算法或者 SPFA 算法来解决。 具体思路如下: 1. 首先,我们需要读入输入数据。输入数据中包含了道路的数量、起点和终点,以及每条道路的起点、终点、长度和限制费用。 2. 接着,我们需要使用邻接表或邻接矩阵来存储图的信息。对于每条道路,我们可以将其起点和终点作为一个有向边的起点和终点,长度作为边权,限制费用作为边权的上界。 3. 然后,我们可以使用 Dijkstra 算法或 SPFA 算法求解从起点到终点的最短路径。在这个过程中,我们需要记录到每个点的最小费用和最小长度,以及更新每条边的最小费用和最小长度。 4. 最后,我们输出从起点到终点的最短路径长度即可。 需要注意的是,在使用 Dijkstra 算法或 SPFA 算法时,需要对每个点的最小费用和最小长度进行松弛操作。具体来说,当我们从一个点 u 经过一条边 (u,v) 到达另一个点 v 时,如果新的费用和长度比原来的小,则需要更新到达 v 的最小费用和最小长度,并将 v 加入到优先队列(Dijkstra 算法)或队列(SPFA 算法)中。 此外,还需要注意处理边权为 0 或负数的情况,以及处理无法到达终点的情况。 代码实现可以参考以下样例代码: ```c++ #include <cstdio> #include <cstring> #include <queue> #include <vector> using namespace std; const int MAXN = 1005, MAXM = 20005, INF = 0x3f3f3f3f; int n, m, s, t, cnt; int head[MAXN], dis[MAXN], vis[MAXN]; struct Edge { int v, w, c, nxt; } e[MAXM]; void addEdge(int u, int v, int w, int c) { e[++cnt].v = v, e[cnt].w = w, e[cnt].c = c, e[cnt].nxt = head[u], head[u] = cnt; } void dijkstra() { priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; memset(dis, 0x3f, sizeof(dis)); memset(vis, 0, sizeof(vis)); dis[s] = 0; q.push(make_pair(0, s)); while (!q.empty()) { int u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; i != -1; i = e[i].nxt) { int v = e[i].v, w = e[i].w, c = e[i].c; if (dis[u] + w < dis[v] && c >= dis[u] + w) { dis[v] = dis[u] + w; q.push(make_pair(dis[v], v)); } } } } int main() { memset(head, -1, sizeof(head)); scanf("%d %d %d %d", &n, &m, &s, &t); for (int i = 1; i <= m; i++) { int u, v, w, c; scanf("%d %d %d %d", &u, &v, &w, &c); addEdge(u, v, w, c); addEdge(v, u, w, c); } dijkstra(); if (dis[t] == INF) printf("-1\n"); else printf("%d\n", dis[t]); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值