算法训练 Airport Configuration

问题描述
  ACM机场是一个本地机场,对于大多数人来说,机场不是他们的终点或起点,而是中转站。机场有一个规划图。到达的大门在机场的北边(相当于空格)。出发的大门在机场的南边(也相当于空格)。两个正对着的大门距离相当于大门间的距离。每一个到达的大门只对应一个城市。每一个出发的大门也是这样。乘客到达的大门对应他们的起始城市,而出发大门对应他们的目标城市。因为这个问题,我们只需考虑转机的乘客。
  转机的乘客会产生机场的交通堵塞。我们已经知道某两个城市之间的平均客流量。用这些信息,有可能能降低交通堵塞。例如,Cx城到Cy城的客流量大,就可以将他们安排得很近,甚至是对位。
  因为花园和商店无法穿越,所以到达门G1和出发们G3(见图)的距离为1+2=3。
  你需要计算几个方案的客流指数。两个大门间的客流指数等于人数乘以距离。而总的客流指数就是所有门之间的客流指数之和。
输入格式
  输入文件有多组测试数据。
  最后一组只有一个0。
  每组测试数据的输入有两部分。先是客流数据,之后是机场布局。
  数据开始时一个n(1<n<25),表示城市数。接下来n行,每行表示一个城市的数据,第i行先是一个整数,表示起始城市,再一个1到n的整数k,表示目标城市数,k对整数,每对描述一个目标城市,第一个数是城市编号j,然后是乘客数目(最多500)从i到j的人数。
  机场布局部分包括1到20个方案。用一个0结束。
  一个方案包括3行。第一行一个数表示编号,第二行是1-n的一个排列,描述到达门对应的城市的排列,第三行用同样的方式描述出发大门。
输出格式
  对于每个测试数据,输出包括一个表格,表示方案编号和客流指数,按照客流指数升序输出。若客流指数相同,则编号小的排在前面。见样例。注意方案编号右对齐,而客流指数左对齐。(样例输出前面4个空格,后面9个空格,然后没有空格,详见未格式化的试题。
样例输入
3
1 2 2 10 3 15
2 1 3 10
3 2 1 12 2 20
1
1 2 3
2 3 1
2
2 3 1
3 2 1
0
2
1 1 2 100
2 1 1 200
1
1 2
1 2
2
1 2
2 1
0
0
样例输出
Configuration Load
2 119
1 122
Configuration Load
2 300
1 600

代码如下:
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef struct node
{
	int num;
	int sum;
	bool operator < (const node& x) const {    //重载函数,按sum的值从小到大排列
		return sum < x.sum;               //PS:博主在写这题的时候,还没弄懂二次重载怎么玩
	}                                        //如果有人会的,可以在这里改一下,大致意思:若sum值相同,按num值从小
}DATA[20];                                      //排列(博主就是因为没弄这个条件,在95分上卡了半天)
int A[25][25],B[26];
int main()
{
	DATA t;
	int n=1, a, b, c, d;
	int sum[20];
	while(1)
	{
		memset(A, 0, sizeof(A));                 //每次循环将数组重置
		cin >> n;
		if (n == 0)                              //区间为0则结束循环
			break;
		for (int i = 0; i < n; i++)
		{
			cin >> a >> b;
			for (int j = 0; j < b; j++)
			{
				cin >> c >> d;
				A[a][c] = d;            //按照权值的方法赋值,可以把关系看作一个图
			}
		}
		int i, l, h;
		for (i = 0; cin >> h && h; i++)
		{
			t[i].num = h;                 //机场样式的编号
			t[i].sum = 0;                     
			for (int j = 1; j <= n; j++)
				cin >> B[j];          //第一行数据
			for (int k = 1; k <= n; k++)
			{
				cin >> l;             //从第二行开始,每输入一次,遍历一次
				for (int j = 1; j <= n; j++)
				{
					t[i].sum += A[B[j]][l] * (abs(j - k) + 1); //abs在这里的作用是求距离
				}
			}
		}
		sort(t, t + i);             //不完全排序(没有排除sum值相同的情况)
		if(i!=0)
			cout << "Configuration Load" << endl;
		for (int j = 0; j < i-1; j++)
		{
			if (t[j].sum == t[j + 1].sum&&t[j].num > t[j + 1].num)
				swap(t[j], t[j + 1]);          //补救重排序
			printf("%d %9d\n", t[j].num, t[j].sum);//按格式输出
		}
		printf("%d %9d\n", t[i-1].num, t[i-1].sum);
	} 
	return 0;
}
这个题可能代码写得比较粗糙,因为博主也还没掌握更好的重载办法,如果有大神知道,可以在评论区指出,多谢

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值