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;
}