(C卷,200分)- 可以处理的最大任务数(Java & JS & Python & C)

题目描述

在某个项目中有多个任务(用task数组表示)需要你进行处理,其中:

  • task[i] = [si, ei]

你可以在 si ≤ day ≤ ei 中的任意一天处理该任务,请返回你可以处理的最大任务数。

输入描述

第一行为任务数量 n

  • 1 ≤ n ≤ 100000

后面 n 行表示各个任务的开始时间和终止时间,使用 si,ei 表示

  • 1 ≤ si ≤ ei ≤ 100000

输出描述

输出为一个整数,表示可以处理的最大任务数。

用例

输入 3
1 1
1 2
1 3
输出 3
说明

题目解析

本题可以利用贪心思维+优先队列来求解。

我们可以将所有任务时间区间按照:优先按照结束时间降序,如果结束时间相同,则按照开始时间降序。这样排序的原因如下:

首先,任务优先按照结束时间降序后,那么第一个任务的结束时间就是最晚的(最大的),此时我们可以让第一个任务就在最晚时刻执行,如下面例子:

3
1 4
2 3
1 2

按照结束时间降序后:[1,4] , [2, 3],  [1, 2] ,第一个任务[1,4]在时刻4执行

这样做的好处是,避免第一个任务抢夺后面任务的执行时间,如下图所示:

  • 如果第一个任务在时刻4执行,则第二个任务就有两个选择,时刻2或时刻3

  • 如果第一个任务在时刻3执行,则第二个任务就只有一个选择,只能在时刻2执行

如果存在多个任务的结束时间都相同的话,则还需要对这些任务按照开始时间降序,这么做的原因是:

  • "时间长" 的任务 "可选执行时刻" 多
  • "时间短" 的任务 "可选执行时刻" 少

因此应该优先让时间跨度短的任务先执行,如下图所示:

  • 如果优先时间短的任务,则三个任务都能执行

  • 如果优先时间长的任务,则只能执行两个任务

但是上面逻辑是存在问题的,请看下面图示:

此时按照前面逻辑的话,只能执行三个任务

但是其实可以执行四个任务,执行策略如下:

主要问题是,当我们按照结束时间降序后,第一个任务选择时刻8执行完,此时后面三个任务的截止时间其实都是相同的,变为了时刻7。

因此,此时我们应该对后面三个任务重新按照时间跨度降序,再优先执行短的任务。

本题数量级较大,因此如果每次执行完一个任务,都对剩余任务进行更新结束时间,并重新排序的话,会超时。

改进策略是,使用优先队列,即:

如果当前任务的结束时间end >= 上一个任务的执行时刻last_end,则更新当前任务的结束为last_end – 1。如果 last_end – 1 > 当前任务开始时间start,则将当前任务重新入队排优先级。否则当前任务不可执行。

Java和Python有内置的优先队列类,而JS和C没有,因此JS和C需要手动实现一个优先队列,关于优先队列的实现原理请看:


经过测试,下面逻辑在本题数量级下会超时:

如果当前任务的结束时间end >= 上一个任务的执行时刻last_end,则更新当前任务的结束为last_end – 1。如果 last_end – 1 > 当前任务开始时间start,则将当前任务重新入队排优先级。否则当前任务不可执行。

因为,我们需要频繁更新任务的结束时间,并且入队出队。

为了避免频繁的更新任务结束时间,以及入队出队,我们可以做如下改动:

1、统计输入的所有任务的时间段,仅按照结束时间降序,得到数组ranges

2、定义一个优先队列pq,仅用于保存任务的开始时间(开始时间越大,优先级越高),我们可以认为优先队列中保存的任务(的开始时间)对应的结束时间都是相同的,我们定义这个公共结束时间为pq_end

3、遍历ranges,得到每一个任务的开始,结束时间range:[start, end],然后比较遍历到任务的end 和 优先队列中所有任务的公共结束时间pq_end:

  • 如果 end < pq_end,则在end ~ pq_end 这段间隔时间内,我们可以从pq中挑选出pq_end – end 个 较短任务进行执行,执行前需要检查 对应任务的开始时间 start <= pq_end,若不满足则不执行。每执行一个任务,则pq_end -= 1,count += 1(count是已执行的任务数量)。当pq_end == end时,则将当前遍历的任务的start 加入 优先队列。

具体过程如下图所示:

JS算法源码

超时解法,但是好理解,是下一种解法的基础
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
  const n = parseInt(await readline());

  // 结束时间越大(越晚)优先级越高,结束时间相同时,开始时间越大(越晚)优先级越高
  const pq = new PriorityQueue((a, b) =>
    a.end != b.end ? b.end - a.end : b.start - a.start
  );

  for (let i = 0; i < n; i++) {
    const [start, end] = (await readline()).split(" ").map(Number);
    pq.offer(new Range(start, end));
  }

  // 记录最大任务数
  let count = 0;

  // 记录上一个任务的执行时刻
  let last_end = Infinity;

  while (pq.size() > 0) {
    const range = pq.poll();

    if (range.end < last_end) {
      // 当前任务结束时刻end < 上个任务结束时刻last_end,则当前任务选择在end时刻执行
      last_end = range.end;
      count++;
    } else if (last_end > range.start) {
      // 当前任务结束时刻end ≥ 上个任务结束时刻last_end,则更新当前任务的结束时间为last_end-1,后重新加入优先队列排队
      // 同时注意range新的结束时间last_end - 1不能小于range.start,否则该任务无法执行
      range.end = last_end - 1;
      pq.offer(range);
    }
  }

  console.log(count);
})();

class Range {
  constructor(start, end) {
    this.start = start;
    this.end = end;
  }
}

// 基于堆实现优先队列
class PriorityQueue {
  constructor(cpr) {
    this.queue = [];
    this.cpr = cpr;
  }

  swap(a, b) {
    const tmp = this.queue[a];
    this.queue[a] = this.queue[b];
    this.queue[b] = tmp;
  }

  // 上浮
  swim() {
    let c = this.queue.length - 1;

    while (c >= 1) {
      const f = Math.floor((c - 1) / 2);

      if (this.cpr(this.queue[c], this.queue[f]) < 0) {
        this.swap(c, f);
        c = f;
      } else {
        break;
      }
    }
  }

  // 入队
  offer(val) {
    this.queue.push(val);
    this.swim();
  }

  // 下沉
  sink() {
    let f = 0;

    while (true) {
      let c1 = 2 * f + 1;
      let c2 = c1 + 1;

      let c;
      let val1 = this.queue[c1];
      let val2 = this.queue[c2];
      if (val1 != undefined && val2 != undefined) {
        c = this.cpr(val1, val2) < 0 ? c1 : c2;
      } else if (val1 != undefined) {
        c = c1;
      } else if (val2 != undefined) {
        c = c2;
      } else {
        break;
      }

      if (this.cpr(this.queue[c], this.queue[f]) < 0) {
        this.swap(c, f);
        f = c;
      } else {
        break;
      }
    }
  }

  // 出队
  poll() {
    this.swap(0, this.queue.length - 1);
    const res = this.queue.pop();
    this.sink();
    return res;
  }

  peek() {
    return this.queue[0];
  }

  size() {
    return this.queue.length;
  }
}
不超时解法
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
  const n = parseInt(await readline());

  const ranges = [];
  for (let i = 0; i < n; i++) {
    ranges.push((await readline()).split(" ").map(Number));
  }

  // 将所有任务按照结束时间降序
  ranges.sort((a, b) => b[1] - a[1]);

  // 优先队列中记录的是任务的开始时间,并且开始时间越大,优先级越高
  const pq = new PriorityQueue((a, b) => b - a);

  // 优先队列中记录的是结束时间相同的任务的开始时间,pq_end就是优先队列中任务的相同结束时间
  let pq_end = Infinity;

  // 最大任务数
  let count = 0;

  // 当前任务的开始和结束时间
  for (let [start, end] of ranges) {
    // 如果当前任务的结束时间 小于 优先队列中记录的任务的结束时间,则两个结束时间之间的间隔时间段,可以处理一些紧急任务
    while (pq.size() > 0 && end < pq_end) {
      // 这里的紧急任务即指时间短的任务,即开始时间比较大的任务
      if (pq.poll() <= pq_end) {
        // 如果紧急任务的开始时间未超过其结束时间,则可以执行
        count++;
        pq_end--; // 一个时刻只执行一个任务
      }
    }

    // 间隔时间消耗完后,优先队列中的任务的结束时间全部更新为当前任务的结束时间
    pq.offer(start);
    pq_end = end;
  }

  // 收尾处理
  while (pq.size() > 0) {
    if (pq.poll() <= pq_end) {
      count++;
      pq_end--;
    }
  }

  console.log(count);
})();

// 基于堆实现优先队列
class PriorityQueue {
  constructor(cpr) {
    this.queue = [];
    this.cpr = cpr;
  }

  swap(a, b) {
    const tmp = this.queue[a];
    this.queue[a] = this.queue[b];
    this.queue[b] = tmp;
  }

  // 上浮
  swim() {
    let c = this.queue.length - 1;

    while (c >= 1) {
      const f = Math.floor((c - 1) / 2);

      if (this.cpr(this.queue[c], this.queue[f]) < 0) {
        this.swap(c, f);
        c = f;
      } else {
        break;
      }
    }
  }

  // 入队
  offer(val) {
    this.queue.push(val);
    this.swim();
  }

  // 下沉
  sink() {
    let f = 0;

    while (true) {
      let c1 = 2 * f + 1;
      let c2 = c1 + 1;

      let c;
      let val1 = this.queue[c1];
      let val2 = this.queue[c2];
      if (val1 != undefined && val2 != undefined) {
        c = this.cpr(val1, val2) < 0 ? c1 : c2;
      } else if (val1 != undefined) {
        c = c1;
      } else if (val2 != undefined) {
        c = c2;
      } else {
        break;
      }

      if (this.cpr(this.queue[c], this.queue[f]) < 0) {
        this.swap(c, f);
        f = c;
      } else {
        break;
      }
    }
  }

  // 出队
  poll() {
    this.swap(0, this.queue.length - 1);
    const res = this.queue.pop();
    this.sink();
    return res;
  }

  peek() {
    return this.queue[0];
  }

  size() {
    return this.queue.length;
  }
}

Java算法源码

超时解法,但是好理解,是下一种解法的基础
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
  static class Range {
    int start;
    int end;

    public Range(int start, int end) {
      this.start = start;
      this.end = end;
    }
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int n = sc.nextInt();

    // 结束时间越大(越晚)优先级越高,结束时间相同时,开始时间越大(越晚)优先级越高
    PriorityQueue<Range> pq =
        new PriorityQueue<>((a, b) -> a.end != b.end ? b.end - a.end : b.start - a.start);

    for (int i = 0; i < n; i++) {
      pq.offer(new Range(sc.nextInt(), sc.nextInt()));
    }

    // 记录最大任务数
    int count = 0;

    // 记录上一个任务的执行时刻
    int last_end = Integer.MAX_VALUE;

    while (pq.size() > 0) {
      Range range = pq.poll();

      if (range.end < last_end) {
        // 当前任务结束时刻end < 上个任务结束时刻last_end,则当前任务选择在end时刻执行
        last_end = range.end;
        count++;
      } else if (last_end > range.start) {
        // 当前任务结束时刻end ≥ 上个任务结束时刻last_end,则更新当前任务的结束时间为last_end-1,后重新加入优先队列排队
        // 同时注意range新的结束时间last_end - 1不能小于range.start,否则该任务无法执行
        range.end = last_end - 1;
        pq.offer(range);
      }
    }

    System.out.println(count);
  }
}
不超时解法
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int n = sc.nextInt();

    int[][] ranges = new int[n][2];
    for (int i = 0; i < n; i++) {
      ranges[i][0] = sc.nextInt();
      ranges[i][1] = sc.nextInt();
    }

    // 将所有任务按照结束时间降序
    Arrays.sort(ranges, (a, b) -> b[1] - a[1]);

    // 优先队列中记录的是任务的开始时间,并且开始时间越大,优先级越高
    PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);

    // 优先队列中记录的是结束时间相同的任务的开始时间,pq_end就是优先队列中任务的相同结束时间
    int pq_end = Integer.MAX_VALUE;

    // 最大任务数
    int count = 0;

    for (int[] range : ranges) {
      // 当前任务的开始和结束时间
      int start = range[0];
      int end = range[1];

      // 如果当前任务的结束时间 小于 优先队列中记录的任务的结束时间,则两个结束时间之间的间隔时间段,可以处理一些紧急任务
      while (pq.size() > 0 && end < pq_end) {
        // 这里的紧急任务即指时间短的任务,即开始时间比较大的任务
        if (pq.poll() <= pq_end) {
          // 如果紧急任务的开始时间未超过其结束时间,则可以执行
          count++;
          pq_end--; // 一个时刻只执行一个任务
        }
      }

      // 间隔时间消耗完后,优先队列中的任务的结束时间全部更新为当前任务的结束时间
      pq.add(start);
      pq_end = end;
    }

    // 收尾处理
    while (pq.size() > 0) {
      if (pq.poll() <= pq_end) {
        count++;
        pq_end--;
      }
    }

    System.out.println(count);
  }
}

Python算法源码

超时解法,但是好理解,是下一种解法的基础
import heapq
import sys


class Range:
    def __init__(self, start, end):
        self.start = start
        self.end = end

    # 结束时间越大(越晚)优先级越高,结束时间相同时,开始时间越大(越晚)优先级越高
    def __gt__(self, other):
        if self.end != other.end:
            return other.end > self.end
        else:
            return other.start > self.start


# 输入获取
n = int(input())

pq = []
for _ in range(n):
    start, end = map(int, input().split())
    heapq.heappush(pq, Range(start, end))


# 算法入口
def getResult():
    # 记录最大任务数
    count = 0

    # 记录上一个任务的执行时刻
    last_end = sys.maxsize

    while len(pq) > 0:
        ran = heapq.heappop(pq)

        if ran.end < last_end:
            # 当前任务结束时刻end < 上个任务结束时刻last_end,则当前任务选择在end时刻执行
            last_end = ran.end
            count += 1
        elif last_end > ran.start:
            # 当前任务结束时刻end ≥ 上个任务结束时刻last_end,则更新当前任务的结束时间为last_end-1,后重新加入优先队列排队
            # 同时注意range新的结束时间last_end - 1不能小于range.start,否则该任务无法执行
            ran.end = last_end - 1
            heapq.heappush(pq, ran)

    return count


# 算法调用
print(getResult())
不超时解法
import heapq
import sys

# 输入获取
n = int(input())
ranges = [list(map(int, input().split())) for _ in range(n)]


# 算法入口
def getResult():
    # 将所有任务按照结束时间降序
    ranges.sort(key=lambda x: -x[1])

    # 优先队列中记录的是任务的开始时间,并且开始时间越大,优先级越高
    # 由于heapq默认是数值越小,优先级越大,因此这里存入负数的开始时间到pq
    pq = []

    # 优先队列中记录的是结束时间相同的任务的开始时间,pq_end就是优先队列中任务的相同结束时间
    pq_end = sys.maxsize

    # 最大任务数
    count = 0

    # 当前任务的开始和结束时间
    for start, end in ranges:
        # 如果当前任务的结束时间 小于 优先队列中记录的任务的结束时间,则两个结束时间之间的间隔时间段,可以处理一些紧急任务
        while len(pq) > 0 and end < pq_end:
            # 这里的紧急任务即指时间短的任务,即开始时间比较大的任务
            if -heapq.heappop(pq) <= pq_end:
                # 如果紧急任务的开始时间未超过其结束时间,则可以执行
                count += 1
                pq_end -= 1  # 一个时刻只执行一个任务

        # 间隔时间消耗完后,优先队列中的任务的结束时间全部更新为当前任务的结束时间
        heapq.heappush(pq, -start)
        pq_end = end

    # 收尾处理
    while len(pq) > 0:
        if -heapq.heappop(pq) <= pq_end:
            count += 1
            pq_end -= 1

    return count


# 算法调用
print(getResult())

C算法源码

超时解法,但是好理解,是下一种解法的基础
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

/* 任务时间段 */
typedef struct {
    int start;
    int end;
} Range;

Range* new_Range(int start, int end) {
    Range* range = (Range*) malloc(sizeof(Range));
    range->start = start;
    range->end = end;
    return range;
}

typedef Range E;

/* 优先队列实现 */
typedef struct PriorityQueue {
    E **arr;
    int size;
    int (*cmp)(const void *, const void *);
} PQ;

PQ *new_PQ(int capacity, int (*cmp)(const void *, const void *)) {
    PQ *pq = (PQ *) malloc(sizeof(PQ));
    pq->arr = (E **) malloc(sizeof(E *) * capacity);
    pq->size = 0;
    pq->cmp = cmp;
    return pq;
}

void swap_PQ(PQ *pq, int a, int b) {
    E *tmp = pq->arr[a];
    pq->arr[a] = pq->arr[b];
    pq->arr[b] = tmp;
}

// 上浮
void swim_PQ(PQ *pq) {
    int c = pq->size - 1;

    while (c >= 1) {
        int f = (c - 1) / 2;

        if (pq->cmp(pq->arr[c], pq->arr[f]) < 0) {
            swap_PQ(pq, c, f);
            c = f;
        } else {
            break;
        }
    }
}

// 入队
void offer_PQ(PQ *pq, E *val) {
    pq->arr[pq->size++] = val;
    swim_PQ(pq);
}

// 下沉
void sink_PQ(PQ *pq) {
    int f = 0;

    while (1) {
        int c1 = 2 * f + 1;
        int c2 = c1 + 1;

        int c;

        if (pq->size > c1 && pq->size > c2) {
            if (pq->cmp(pq->arr[c1], pq->arr[c2]) < 0) {
                c = c1;
            } else {
                c = c2;
            }
        } else if (pq->size > c1 && pq->size <= c2) {
            c = c1;
        } else if (pq->size <= c1 && pq->size > c2) {
            c = c2;
        } else {
            break;
        }

        if (pq->cmp(pq->arr[c], pq->arr[f]) < 0) {
            swap_PQ(pq, c, f);
            f = c;
        } else {
            break;
        }
    }
}

// 出队
E *poll_PQ(PQ *pq) {
    swap_PQ(pq, 0, pq->size - 1);
    E *res = pq->arr[--pq->size];
    sink_PQ(pq);
    return res;
}

int cmp(const void *a, const void *b) {
    Range *A = (Range *) a;
    Range *B = (Range *) b;
    // 结束时间越大(越晚)优先级越高,结束时间相同时,开始时间越大(越晚)优先级越高
    return A->end != B->end ? B->end - A->end : B->start - A->start;
}

int main() {
    int n;
    scanf("%d", &n);

    // 结束时间越大(越晚)优先级越高,结束时间相同时,开始时间越大(越晚)优先级越高
    PQ* pq = new_PQ(n, cmp);

    for (int i = 0; i < n; i++) {
        int start, end;
        scanf("%d %d", &start, &end);
        offer_PQ(pq, new_Range(start, end));
    }

    // 记录最大任务数
    int count = 0;

    // 记录上一个任务的执行时刻
    int last_end = INT_MAX;

    while (pq->size > 0) {
        Range* range = poll_PQ(pq);

        if (range->end < last_end) {
            // 当前任务结束时刻end < 上个任务结束时刻last_end,则当前任务选择在end时刻执行
            last_end = range->end;
            count++;
        } else if (last_end > range->start) {
            // 当前任务结束时刻end ≥ 上个任务结束时刻last_end,则更新当前任务的结束时间为last_end-1,后重新加入优先队列排队
            // 同时注意range新的结束时间last_end - 1不能小于range.start,否则该任务无法执行
            range->end = last_end - 1;
            offer_PQ(pq, range);
        }
    }

    printf("%dn", count);

    return 0;
}
不超时解法

 

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef int E;

/* 优先队列实现 */
typedef struct PriorityQueue {
    E *arr;
    int size;

    int (*cmp)(E, E);
} PQ;

PQ *new_PQ(int capacity, int (*cmp)(E, E)) {
    PQ *pq = (PQ *) malloc(sizeof(PQ));
    pq->arr = (E *) malloc(sizeof(E) * capacity);
    pq->size = 0;
    pq->cmp = cmp;
    return pq;
}

void swap_PQ(PQ *pq, int a, int b) {
    E tmp = pq->arr[a];
    pq->arr[a] = pq->arr[b];
    pq->arr[b] = tmp;
}

// 上浮
void swim_PQ(PQ *pq) {
    int c = pq->size - 1;

    while (c >= 1) {
        int f = (c - 1) / 2;

        if (pq->cmp(pq->arr[c], pq->arr[f]) < 0) {
            swap_PQ(pq, c, f);
            c = f;
        } else {
            break;
        }
    }
}

// 入队
void offer_PQ(PQ *pq, E val) {
    pq->arr[pq->size++] = val;
    swim_PQ(pq);
}

// 下沉
void sink_PQ(PQ *pq) {
    int f = 0;

    while (1) {
        int c1 = 2 * f + 1;
        int c2 = c1 + 1;

        int c;

        if (pq->size > c1 && pq->size > c2) {
            if (pq->cmp(pq->arr[c1], pq->arr[c2]) < 0) {
                c = c1;
            } else {
                c = c2;
            }
        } else if (pq->size > c1 && pq->size <= c2) {
            c = c1;
        } else if (pq->size <= c1 && pq->size > c2) {
            c = c2;
        } else {
            break;
        }

        if (pq->cmp(pq->arr[c], pq->arr[f]) < 0) {
            swap_PQ(pq, c, f);
            f = c;
        } else {
            break;
        }
    }
}

// 出队
E poll_PQ(PQ *pq) {
    swap_PQ(pq, 0, pq->size - 1);
    E res = pq->arr[--pq->size];
    sink_PQ(pq);
    return res;
}

int cmp(const void *a, const void *b) {
    int *A = (int *) a;
    int *B = (int *) b;
    return B[1] - A[1];
}

int cmp_PQ(int a, int b) {
    return b - a;
}

int main() {
    int n;
    scanf("%d", &n);

    int ranges[n][2];
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &ranges[i][0], &ranges[i][1]);
    }

    // 将所有任务按照结束时间降序
    qsort(ranges, n, sizeof(ranges[0]), cmp);

    // 优先队列中记录的是任务的开始时间,并且开始时间越大,优先级越高
    PQ *pq = new_PQ(n, cmp_PQ);

    // 优先队列中记录的是结束时间相同的任务的开始时间,pq_end就是优先队列中任务的相同结束时间
    int pq_end = INT_MAX;

    // 记录最大任务数
    int count = 0;


    for (int i = 0; i < n; i++) {
        // 当前任务的开始和结束时间
        int start = ranges[i][0];
        int end = ranges[i][1];

        // 如果当前任务的结束时间 小于 优先队列中记录的任务的结束时间,则两个结束时间之间的间隔时间段,可以处理一些紧急任务
        while (pq->size > 0 && end < pq_end) {
            // 这里的紧急任务即指时间短的任务,即开始时间比较大的任务
            if (poll_PQ(pq) <= pq_end) {
                // 如果紧急任务的开始时间未超过其结束时间,则可以执行
                count++;
                pq_end--;// 一个时刻只执行一个任务
            }
        }

        // 间隔时间消耗完后,优先队列中的任务的结束时间全部更新为当前任务的结束时间
        offer_PQ(pq, start);
        pq_end = end;
    }

    // 收尾处理
    while (pq->size > 0) {
        if (poll_PQ(pq) <= pq_end) {
            count++;
            pq_end--;
        }
    }

    printf("%dn", count);

    return 0;
}

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?