题目意思: 有n个人在比m米的比赛,现在给出这n个人的当前位置,(起点为0,0-399),以及这n个人的排名,问我么给出的排列是否正确
解题思路: 我们知道对于第一名来说他跑的总的距离是比第二名多的,第二名比第三,依次.......
首先我么应该先对这n个人的排名进行排序,使得它们从小到大(第一名.....最后一名)。
那么我么知道如果是正确的话,x从上到下必须是降序排列,如果当前这个人的x比前面人大,说明这个人被套圈了,那么就应该使这个人前面所有的人x对应加上400,直到最后这个x序列是降序为止。
那么最后只要判断第一名的x值是不是不超过m即可,如果是就是YES,否则NO
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
#define MAXN 110
int t , n , m;
int flag;
int x[MAXN] , r[MAXN];
int tmp_x[MAXN] , tmp_r[MAXN];//存储排序后的位置以及排名
//查找哪一个比它前面的大
int search(){
for(int i = 1 ; i < n ; i++){
if(tmp_x[i] > tmp_x[i-1]) return i;
}
return 0;
}
//处理函数
void solve(){
int k;
memset(tmp_x , 0 , sizeof(tmp_x));
memcpy(tmp_r , r , sizeof(r));
sort(tmp_r , tmp_r+n);//先排序
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(tmp_r[i] == r[j]){
tmp_x[i] = x[j] ; break;//tmp_x数组赋值
}
}
}
while(k = search()){
for(int i = 0 ; i < k ; i++) tmp_x[i] += 400;//前面人加400
}
if(tmp_x[0] <= m) flag = 1;//判断是否不大于m即可
}
//主函数
int main() {
//freopen("input.txt" , "r" , stdin);
scanf("%d" , &t);
while(t--){
memset(x , 0 , sizeof(x));
memset(r , 0 , sizeof(r));
scanf("%d%d" ,&n , &m);
for(int i = 0 ; i < n ; i++)
scanf("%d%d" , &x[i] , &r[i]);
flag = 0 ; solve();
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}