Codeforces Round #615 (Div. 3)
传送门:http://codeforces.com/contest/1294/problem/B
测试样例:
input
3
5
1 3
1 2
3 3
5 5
4 3
2
1 0
0 1
1
4 3
output
YES
RUUURRRRUU
NO
YES
RRRRUUU
Note
For the first test case in the example the optimal path RUUURRRRUU is shown below:
题目大意:机器人在(0,0)位置,有n个坐标存在n个包裹,机器人只能向上(U)或者向右(R)移动。给定t个测试样例,每个测试样例包含n和n个坐标,机器人希望收集所有的n个包(按任意顺序排列,他想用尽可能少的动作来做这件事。如果有几个可能的遍历,机器人希望选择字典最小的路径。)如果可以,输出YES并输出走的步骤,否则输出NO。
思路:如果存在任意两个坐标一个在另一个的左上角则无法收集所有的包,否则可以。将所有坐标按x,y由小到大排序,依次遍历即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int x,y;
}p[1005];
bool cmp(struct Node a,struct Node b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p,p+n,cmp);
int x=0,y=0;
int flag=0;
for(int i=0;i<n;i++)
{
for(int j=i;j<n;j++)
if(p[i].x<p[j].x&&p[i].y>p[j].y)
{
flag=1;
break;
}
if(flag)
break;
}
if(flag)
{
printf("NO\n");
continue;
}
else
{
printf("YES\n");
for(int i=0;i<n;i++)
{
int num=p[i].x-x;
for(int j=0;j<num;j++)
printf("R");
num=p[i].y-y;
for(int j=0;j<num;j++)
printf("U");
x=p[i].x;
y=p[i].y;
}
printf("\n");
}
}
return 0;
}
AC代码2(优化):
如果存在任意两个点一个在另一个左上角,必然存在前一个在后一个左上角。可将双重for循环优化为一重,O(n^2)变为O(n)。
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int x,y;
}p[1005];
bool cmp(Node a,Node b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p,p+n,cmp);
int flag=0;
for(int i=1;i<n;i++)//优化O(n^2)为O(n)
{
if(p[i-1].x<p[i].x&&p[i-1].y>p[i].y)
{
flag=1;
break;
}
}
if(flag)
{
printf("NO\n");
continue;
}
else
{
printf("YES\n");
int x=0,y=0;
for(int i=0;i<n;i++)
{
int num1=p[i].x-x,num2=p[i].y-y;
for(int j=0;j<num1;j++)
printf("R");
for(int j=0;j<num2;j++)
printf("U");
x=p[i].x;
y=p[i].y;
}
printf("\n");
}
}
return 0;
}