B - Mahmoud the Thief(CFGym 102152B)

B - Mahmoud the Thief(CFGym 102152B)_第1张图片
题意:有n个文件,m个空间,q次询问,下面给出n个文件各自所占的空间从x到y,输入q个数,每次询问输出这个字节所占的标号最大的空间
如果没有这么大的空间就输出-1 -1
Input
2
3 9 2
1 1
5 5
8 9
3
2
2 5 3
5 5
1 2
1
2
4
Output
2 4
6 7
4 4
3 4
-1 -1

代码:
思路:用一个标记数组区分有文件存放的内存和无文件存放的,逆向遍历空间大小,如果大小为x的空间已存入值就不改变了,因为存的肯定是最大的l和r,如果没有存下就是当前的区间值

#include 
#include 
#include 
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define fori(a,b) for(int i=a; i<=b; ++i)
#define forj(a,b) for(int j=a; j<=b; ++j)
using namespace std;

int a[100010];
bool vis[100010];
struct A
{
    int s, e;
} b[100010];

int main()
{
    int T, n, m, q, l, r, x;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d %d", &n, &m, &q);
        bool flag=1;
        int left=m, right=m, maxlen=0;
        mem(a, 0);
        mem(vis, 0);
        mem(b,0);
        fori(1, n)
        {
            scanf("%d %d", &l, &r);
            forj(l, r)
               a[j] = 1;
        }

        int num = 1;

        for(int i=m;i>=1;i--){
            if(a[i] == 1){
                num = 1;
            }
            else{
                if(b[num].s == 0){
                   b[num].s = i;
                   b[num].e = i+num-1;
                }
                maxlen =max(maxlen,num);
                num++;
            }
        }


        fori(1, q)
        {
            scanf("%d", &x);
            if(x>maxlen)
                printf("-1 -1\n");
            else
                printf("%d %d\n", b[x].s, b[x].e);
        }
    }
    return 0;
}

你可能感兴趣的:(ACM)