一 简单田忌赛马
田忌赛马 描述
田忌和齐王各自都有N匹马 每一匹马都有一个速度值(速度值为正整数 数值越大表示马跑得越快) 双方约定:
1每一轮比赛 双方各自出一匹马对决 每一匹马只能出场一次
2谁的马速度快谁就获胜
3速度相等则平局
请你设计策略 让田忌尽可能赢更多的比赛 最终输出田忌能赢的最大胜场数
输入格式
第一行输入一个整数 N(1 ≤ N ≤ 10^5)表示双方马匹的数量
第二行输入 N 个整数 表示田忌的 N 匹马的速度值(用空格分隔)
第三行输入 N 个整数 表示齐王的 N 匹马的速度值(用空格分隔)
输出格式
输出一个整数,表示田忌能赢的最大胜场数
1基本策略
我想让田忌能赢得最多
先排序 从大到小
四个指针int型
指向
-------田忌最大的马 ------田忌最小的马
-------齐王最大的马 ------齐王最小的马
(其实排序后 每一个数组的0 N-1 0 N-1位置)
让田忌最大的马 和 齐王最大的马比较
如果能赢 直接上场
如果不能赢 反正怎么样都不可能赢了 就用田忌最小的 马去和齐王最大的马 上场比赛 比赛一定会输 但是浪费的是田忌最小的马 浪费的最小化了
2我的代码(求指点)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int N;
cin>>N;
vector<int>tian(N);
vector<int>qi(N);
for(int i=0;i<N;++i)cin>>tian[i];
for(int i=0;i<N;++i)cin>>qi[i];
sort(tian.begin(),tian.end(),greater<int>() );
sort(qi.begin(),qi.end(),greater<int>() );
int t_fast=0,t_slow=N-1;
int q_fast=0,q_slow=N-1;
int winCnt=0;
while(t_fast<=t_slow){
if(tian[t_fast] > qi[q_fast] ){//田忌能赢 就直接赢
t_fast++;
q_fast++;
winCnt++;
}else{
//当田忌最快的马 < 齐王最快的马 这时候一定不会赢 平局和输是一个效果:都不会winCnt++
// 所以直接让田忌最小的马去消耗齐王最大的马 即可
t_slow--;
q_fast++;
}
}
//输出赢的次数
cout<<winCnt<<endl;
}
二 洛谷 进阶P1650 田忌赛马
我国历史上有个著名的故事: 那是在 230023002300 年以前。齐国的大将军田忌喜欢赛马。他经常和齐王赛马。他和齐王都有三匹马:常规马,上级马,超级马。一共赛三局,每局的胜者可以从负者这里取得 200200200 银币。每匹马只能用一次。齐王的马好,同等级的马,齐王的总是比田忌的要好一点。于是每次和齐王赛马,田忌总会输 600600600 银币。
田忌很沮丧,直到他遇到了著名的军师――孙膑。田忌采用了孙膑的计策之后,三场比赛下来,轻松而优雅地赢了齐王 200200200 银币。这实在是个很简单的计策。由于齐王总是先出最好的马,再出次好的,所以田忌用常规马对齐王的超级马,用自己的超级马对齐王的上级马,用自己的上级马对齐王的常规马,以两胜一负的战绩赢得 200200200 银币。实在很简单。
如果不止三匹马怎么办?这个问题很显然可以转化成一个二分图最佳匹配的问题。把田忌的马放左边,把齐王的马放右边。田忌的马 A 和齐王的 B 之间,如果田忌的马胜,则连一条权为 200200200 的边;如果平局,则连一条权为 000 的边;如果输,则连一条权为 −200-200−200 的边……如果你不会求最佳匹配,用最小费用最大流也可以啊。 然而,赛马问题是一种特殊的二分图最佳匹配的问题,上面的算法过于先进了,简直是杀鸡用牛刀。现在,就请你设计一个简单的算法解决这个问题。
输入格式
第一行一个整数 nnn ,表示他们各有几匹马(两人拥有的马的数目相同)。第二行 nnn 个整数,每个整数都代表田忌的某匹马的速度值($0 \le $ 速度值 ≤100\le 100≤100)。第三行 nnn 个整数,描述齐王的马的速度值。两马相遇,根据速度值的大小就可以知道哪匹马会胜出。如果速度值相同,则和局,谁也不拿钱。
输出格式
仅一行,一个整数,表示田忌最大能得到多少银币。
输入输出样例 #1
输入 #1
3
92 83 71
95 87 74
输出 #1
200
数据规模与约定
- 对于 20%20\%20% 的数据,1≤N≤651\le N\le 651≤N≤65;
- 对于 40%40\%40% 的数据,1≤N≤2501\le N\le 2501≤N≤250;
- 对于 100%100\%100% 的数据,1≤N≤20001\le N\le20001≤N≤2000。
1我的代码
//AC了
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int N;
cin>>N;
vector<int>tian(N);
vector<int>qi(N);
for(int i=0;i<N;++i)cin>>tian[i];
for(int i=0;i<N;++i)cin>>qi[i];
sort(tian.begin(),tian.end(),greater<int>() );
sort(qi.begin(),qi.end(),greater<int>() );
int t_fast=0,t_slow=N-1;
int q_fast=0,q_slow=N-1;
int res=0;
while(t_fast<=t_slow){
if(tian[t_fast] > qi[q_fast] ){
res+=200;
t_fast++;
q_fast++;
}else if(tian[t_fast] < qi[q_fast] ){
t_slow--;
q_fast++;
res-=200;
}else if(tian[t_fast]==qi[q_fast] ){
if(tian[t_slow] > qi[q_slow] ){
t_slow--;
q_slow--;
res+=200;
}else{
if(tian[t_slow] < qi[q_fast] ){
res-=200;
}
t_slow--;
q_fast++;
}
}
}
//
cout<<res<<endl;
}
这个代码AC了
4ms/788.00KB
AC
#1
Accepted, 得分 10.ok accepted
5ms/1.04MB
AC
#2
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#3
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#4
Accepted, 得分 10.ok accepted
5ms/788.00KB
AC
#5
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#6
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#7
Accepted, 得分 10.ok accepted
4ms/788.00KB
AC
#8
Accepted, 得分 10.ok accepted
4ms/816.00KB
AC
#9
Accepted, 得分 10.ok accepted
5ms/808.00KB
AC
#10
Accepted, 得分 10.ok accepted
三 这两题核心要点
先说第一题
第一题
if 田忌t_fast > 齐王q_fast 直接比赛winCnt+1
if 田忌t_fast < 齐王q_fast 一定会winCnt不变 反正不管怎么样都会输 就让田忌t_slow 去消耗齐王q_fast
if 田忌t_fast齐王q_fast 一定winCnt不变 反正怎么样都不会winCnt++ 就直接让田忌t_slow 去消耗齐王q_fast
< 和可以合并再一起
再说第二题
if 田忌t_fast > 齐王q_fast 直接比赛res+200
if 田忌t_fast < 齐王q_fast 反正不管怎么样都会输 就让田忌t_slow 去消耗齐王q_fast res-200
if 田忌t_ fast == 齐王q_fast 细说
如果田忌最快 == 齐王最快,不能直接送掉,要判断田忌最慢能否吃掉齐王最慢
如果能 → 就让最慢打最慢(+200)
不能 → 才让最慢打最快
自己的碎碎念 (随便写)
//纪念一下自己这几个月的努力
//已经得偿所愿了 转到计算机了
//接下来会继续坚持学习算法
//one can walk for alone

//机考那天做的题

//有几道实在WA
//啊啊啊

//当时刷PTA建的文件夹
//知道要靠PTA就反复刷
//温故而知新



































//PTA刷透就开始刷leetcode了
//leetcode只刷了大概100道
//嫌丢人 太菜了 就不展示图片了
//哈哈哈
909

被折叠的 条评论
为什么被折叠?



