携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
题目描述:
田忌与齐王赛马,双方各有n匹马参赛,每场比赛赌注为200两黄金,现已知齐王与田忌的每匹马的速度,并且齐王肯定是按马的速度从快到慢出场,现要你写一个程序帮助田忌计算他最好的结果是赢多少两黄金。
说明: 为了简单起见,保证2n匹马的速度均不相同。
输入格式:
输入每组测试数据占3行,第一行是n(n<=1000),表示双方参赛马的数量,第2行n个正整数,表示田忌的马的速度,第3行n个正整数,表示齐王的马的速度.测试数据以“0”结束。
输出格式:
每组测试数据输出一行数据,表示田忌比赛的最好结果是赢多少两黄金。
输入样例:
3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0
输出样例:
200
0
0
代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
初看:不好处理
细看:找最优解,贪心算法
思路分析:
vector动态数组记录田忌和齐王的马质量,由于需要有一定的排序来做题,所以直接用vector排序功能
每次循环记录赢得次数
当田忌最慢的马比齐王最慢的马快时
- 赢得次数加一
- 然后让田忌与齐王的低位指针+1
当田忌最快的马比齐王最快的马快时
- 赢得次数加一
- 田忌和齐王高位指针减一
最后如果田忌最慢的马比齐王最快的马快时
- 赢得次数减一
最后赢得次数乘以200输出即可
代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n;
vector<int>TJ, QW;
while (1) {
int win_cnt = 0, x;
cin >> n;
if (n == 0)
break;
for (int i = 0; i < n; i++) {
cin >> x;
TJ.push_back(x);
}
for (int i = 0; i < n; i++) {
cin >> x;
QW.push_back(x);
}
//sort排序一下
sort(TJ.begin(), TJ.end());
sort(QW.begin(), QW.end());
int T_high = n - 1, Q_high = n - 1;
int T_low = 0, Q_low = 0;
while (T_low <= T_high) {
//当田忌最慢的马比齐王最慢的马快时
if (TJ[T_low] > QW[Q_low]) {
win_cnt++;
T_low++;
Q_low++;
}
//当田忌最快的马比齐王最快的马快时
else if (TJ[T_high] > QW[Q_high]) {
win_cnt++;
T_high--;
Q_high--;
}
else {
//用田忌最慢的马比齐王最快的马
if (TJ[T_low] < QW[Q_high])
win_cnt--;
//如果平局就直接下一步
T_low++;
Q_high--;
}
}
cout << win_cnt * 200 << endl;
QW.clear();
TJ.clear();
}
}
PS:成功解题=理清思路+一定的技巧~