NYOJ220&&HDU1050--Move tables

【题意】:给你一些房间编号,让你按要求移动桌子,区间【a,b】表示要把桌子从a号房间移动到b号房间,注意之后还会有区间移动,但是要注意之前的区间内房间之间的走廊已被占用,求出按要求移动所有桌子的最小时间。

链接: click here

思路:在定义的结构体里面再加一个visit变量,用于是否标记,然后按开始时间升序排列,从i=0开始遍历,首先找到未visit的区间,如果找到,则num+=10(后面就开始寻找和这个区间能够同时搬运的区间),保留第i个区间的结束处last,然后嵌套遍历,j从i+1到n-1,若第j个区间的开始大于last,则在这10分钟内可以同时用第j个区间,修改last,标记第j个区间为已经visit。
还有一个思路:其实就是区间选择不相交问题,nyoj将其分类为贪心的题,其实可以用重叠的思路,不妨这样设想,将2,1房间,4,3,房间,6,5,房间统一考虑,将他们的空地分别标记为room[i], 如果你想把东西从n搬到m,那么自然的空地room[(n+1)/2]到空地room[(m+1)/2]都会用到,将这里标记上。然后重复,最后数组中重叠数最多的,必定会冲突到得次数,所以答案为最大的room[i]*10(分钟)。

两种代码:

#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define max(a,b) a>b?a:b
#define min(a,b) a>b?b:a
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
#define PI 3.1415926
struct node
{
    int i,j,visit;
} room[201];
int ans[201];
bool cmp(node x,node y)
{
    if(x.i!=y.i)
        return x.i<y.i;
}
int main()
{
    //mem(room,0);
    int t,n,m,i,j;
    scanf("%d",&t);
    while(t--)
    {
        int cmx,cmy;
        int ss=0;
        scanf("%d",&n);
        mem(room,0);
        for(i=0; i<n; i++)
        {
            scanf("%d%d",&cmx,&cmy);
            cmx=(cmx+1)/2,cmy=(cmy+1)/2;//比如3,4 都要化成2
            if(cmx>cmy)
            {
                int tt=cmx;
                cmx=cmy;
                cmy=tt;
               // swap(cmx,cmy);
            }
            room[i].i=cmx,room[i].j=cmy;
        }
        sort(room,room+n,cmp);
        for(i=0; i<n; i++)
        {
            if(room[i].visit==0)
            {
                //ru guo chan guan=0;
                ss+=10;
                int last=room[i].j;
                for(j=i+1; j<n; j++)
                {
                    if(room[j].visit==0&&room[j].i>last)
                    {
                        room[j].visit=1;
                        last=room[j].j;
                    }
                }
            }
        }
        printf("%d\n",ss);
    }
    return 0;
}
/*
3
4
10 20
30 40
50 60
70 80
2
1 3
2 200
3
10 100
20 80
30 50
*/  
第二种:

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[202];
int main()
{

    int n,m,i,j;
    scanf("%d",&n);
    while(n--)
    {
        int aa,bb;
        scanf("%d",&m);
        memset(a,0,sizeof(a));
        for(i=0;i!=m;i++)
        {
            scanf("%d%d",&aa,&bb);
            if(aa>bb) swap(aa,bb);
            for(j=(aa-1)/2;j<=(bb-1)/2;j++)
                a[j]++;
        }
        printf("%d\n",*max_element(a,a+202)*10);
    }
    return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值