CF-1294-B Collecting Packages

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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值