1004. Distinct Values

2018-07-27  本文已影响0人  laochonger

1004. Distinct Values

题意:给出n,m;n代表右一个由n个1到n的数组成的数组,m表示m个限制条件,每个限制条件由两个数组成,在这两个数的区间内所有的数不重复,求字母序最小的满足所有限制条件的数组。
思路:
标程:可以从左往右贪心,问题转化成求一个区间里的mex,由于区间左右端点都是递增的,用个set维护下 即可。
赛时:先对条件进行排序,选择尽量长的条件,放弃被覆盖的条件。然后用一个数组进行标记,表示这个数是否用过,每次往下时要解锁上一个并用循环寻找下一个最小未被标记数进行标记,并且对相交与否进行分类,很明显,结果正确,但TLE了。

标程:

#include <cstdio>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
 
int main() {
  int T;
  scanf("%d", &T);
  for (int cas = 1; cas <= T; ++cas) {
    int n, m;
    scanf("%d%d", &n, &m);
    vector<int> ends(n, -1);
    for (int i = 0; i < n; ++i) ends[i] = i;
    for (int i = 0; i < m; ++i) {
      int l, r;
      scanf("%d%d", &l, &r);
      ends[l - 1] = max(ends[l - 1], r - 1);
    }
    set<int> unused;
    for (int i = 1; i <= n; ++i) {
      unused.insert(i);
    }
    vector<int> ret(n);
    int l = 0, r = -1;
    for (int i = 0; i < n; ++i) {
      if (r >= ends[i]) continue;
      while (l < i) {
        unused.insert(ret[l++]);
      }
      while (r < ends[i]) {
        ret[++r] = *unused.begin();
        unused.erase(ret[r]);
      }
    }
    for (int i = 0; i < n; ++i) {
      if (i) putchar(' ');
      printf("%d", ret[i]);
    }
    puts("");
  }
  return 0;
}

赛程:

//B17040312
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;


    int pos1[100005];
    int pos2[100005];
    int slove[100005];
    struct point{
        int x;
        int y;
    }p[100005];

    bool cmp(const point &a , const point &b){
        if(a.x<b.x) return true;
        else if(a.x>b.x) return false;
        else{
            return a.y>b.y;
        }
    }


int main(){
    int t,n,m;
    scanf("%d", &t);
    while(t--){
        scanf("%d %d", &n ,&m);
        for(int i = 1; i <= m; i++){
            scanf("%d%d", &p[i].x,&p[i].y);
        }
    
        for(int i = 1; i <= n; i++){
            slove[i] = 1;
            pos1[i] = 1;
            pos2[i] = 1;
        }
        sort(p+1, p+m+1,cmp);
        for(int i = 1; i <= m; i++){
            if(pos1[p[i].x]==0&&pos1[p[i].y]==0) continue;
            else if(pos1[p[i].x]==0&&pos1[p[i].y]!=0){
                for(int j = p[i-1].x; j < p[i].x; j++){
                    pos2[slove[j]] = 1;
                }
                for(int j = p[i-1].y+1; j <= p[i].y; j++){
                    pos1[j] = 0;
                    for(int q = 1; q <= n; q++){
                        if(pos2[q] == 1){
                            slove[j] = q;
                            pos2[q] = 0;
                            break;
                        }
                    }
                }
            
            }else{
                if(i != 1){
                    for(int j = p[i-1].x; j <= p[i-1].y; j++){
                        pos2[slove[j]] = 1;
                    }
                }
                int h = 1;
                for(int j = p[i].x; j <= p[i].y; j++){
                    slove[j] = h++;
                    pos2[h-1] = 0;
                    pos1[j] = 0;
                }
            }
        }
        for(int i = 1; i <= n; i++){
            printf("%d", slove[i]);
            if(i == n) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读