题目意思: 有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; }