列表

详情


NC25252. 集结

描述

    张老师一直希望同济大学能够进入ICPC的World Final,但是觉得同济大学ACM队太弱了。他想召集世界各地的上古大神来带领同济ACM队进行训练。
    假设世界是一个1*n的一维地图,所有格子的坐标都是1到n之间的整数。一开始地图上某一些格子有一位上古大神,其他的格子会有一些事件。每个格子里面只有一位上古大神或者只有一个事件。张老师希望能请到上古大神能集中到一个格子上。
约定集结的坐标点之后,上古大神们依次开始移动。每一次有一位上古大神向着集结的坐标直线前进,不会向相反方向走。当一位上古大神进入一个格子的时候,如果这个格子里面有一个事件没有触发,那么就会触发这个事件让上古大神获得或者失去一些体力。当上古大神某一个时刻体力小于0的时候就不能到达集结点了(等于0依然可以到达)。一个事件只会触发一遍,已经触发过之后就不会再触发了。一位上古大神移动结束之后,另一位上古大神才开始移动。
张老师希望能将上古大神都请过来,但是不知道怎么安排集结点和移动顺序才能让所有人都能到达。他想让你规划一个集结的方案。
注意所有上古大神都需要移动且仅移动一次,即使是和集结点在一个坐标上也需要移动。

输入描述

    第一行两个整数n,m(1<=m<=n<=100,000)表示格子的个数是n,一共有m位上古大神
    接下来m行,有2个整数ai,b(1<=ai<=n, 1<=bi<=1,000,000),表示第i位上古大神在坐标ai的位置上,有bi的体力。保证上古大神初始不会在同一共位置上
    接下来一行,包括n个整数c1,c2......cn,第i个整数ci(-1,000,000<=ci<=1,000,000)表示坐标为i的位置的情况:
    等于0:这个位置有一位上古大神;
    不等于0:这个位置有一个事件。

输出描述

第一行输出一个数代表集结点。
第二行输出m个数,第i个数代表第i个移动的上古大神序号。这个序号和输入的顺序相同。
如果有多种方案,输出任意一种。如果不能使所有人都到达,那么输出-1。

示例1

输入:

8 3
1 15
8 1
5 10
0 -5 -5 -5 0 -5 -5 0

输出:

7
3 1 2

说明:

一个1*8的格子,初始在1、5、8的地方都有一个上古大神,体力是15、10、1。选择7作为集结点。
一开始第3个(坐标为5)上古大神移动,走到7,经历了6和7的事件,体力变成0。等于0依然可以到达。
然后第1个(坐标为1)上古大神移动,经历了2、3、4的事件体力变成0,然后因为6和7的事件已经被触发,体力不变,最终到达7。
最后移动第2个(坐标为8)上古大神,移动到7体力不变。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 37ms, 内存消耗: 4760K, 提交时间: 2019-04-24 10:49:30

#include <bits/stdc++.h>
#define MAX_N 100005
#define DEBUG 0
#define a first
#define b second
using namespace std;

typedef pair<int, long long> P;
int n, m;
P master[MAX_N];
int c[MAX_N];
P mp[MAX_N];
int id[MAX_N];
int vis[MAX_N];
stack<P> l;
stack<P> r;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 1 ; i <= m; i++) {
    cin >> master[i].a >> master[i].b;
    mp[master[i].a] = master[i];
    id[master[i].a] = i;
  }
  for (int i = 1; i <= n; i++) cin >> c[i];
  sort(master + 1, master + m + 1);
  P curr = master[1];
  int max_l = master[1].a;
  l.push(curr);
  for (int i = master[1].a; i <= n; i++) {
    curr.b += c[i];
    if (curr.b < 0) break;
    max_l = max(max_l, i);
    if (!c[i]) {
      P p = mp[i];
      if (p.b > curr.b) {
        curr = p;
        l.push(curr);
      }
    }
  }
  curr = master[m];
  int max_r = master[m].a;
  r.push(curr);
  for (int i = master[m].a; i >= 1; i--) {
    curr.b += c[i];
    if (curr.b < 0) break;
    max_r = min(max_r, i);
    if (!c[i]) {
      P p = mp[i];
      if (p.b > curr.b) {
        curr = p;
        r.push(curr);
      }
    }
  }
  #if DEBUG
  cout << "max_l: " << max_l << endl;
  cout << "max_r: " << max_r << endl;
  #endif
  if (max_l + 1 < max_r) {
    cout << -1 << endl;
  }
  else {
    int target = max_l;
    memset(vis, 0, sizeof vis);
    cout << target << endl;
    while (!l.empty()) {
      P p = l.top();
      l.pop();
      if (vis[id[p.a]]) continue;
      cout << id[p.a] << ' ';
      vis[id[p.a]] = 1;
    }
    while (!r.empty()) {
      P p = r.top();
      r.pop();
      if (vis[id[p.a]]) continue;
      cout << id[p.a] << ' ';
      vis[id[p.a]] = 1;
    }
    for (int i = 1; i <= m; i++) {
      if (vis[i]) continue;
      cout << i << ' ';
    }
    cout << endl;
  }
  return 0;
}

C++14(g++5.4) 解法, 执行用时: 40ms, 内存消耗: 4884K, 提交时间: 2019-04-25 12:07:50

#include <bits/stdc++.h>
#define MAX_N 100005
#define DEBUG 0
#define a first
#define b second
using namespace std;
 
typedef pair<int, long long> P;
int n, m;
P master[MAX_N];
int c[MAX_N];
P mp[MAX_N];
int id[MAX_N];
int vis[MAX_N];
stack<P> l;
stack<P> r;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 1 ; i <= m; i++) {
    cin >> master[i].a >> master[i].b;
    mp[master[i].a] = master[i];
    id[master[i].a] = i;
  }
  for (int i = 1; i <= n; i++) cin >> c[i];
  sort(master + 1, master + m + 1);
  P curr = master[1];
  int max_l = master[1].a;
  l.push(curr);
  for (int i = master[1].a; i <= n; i++) {
    curr.b += c[i];
    if (curr.b < 0) break;
    max_l = max(max_l, i);
    if (!c[i]) {
      P p = mp[i];
      if (p.b > curr.b) {
        curr = p;
        l.push(curr);
      }
    }
  }
  curr = master[m];
  int max_r = master[m].a;
  r.push(curr);
  for (int i = master[m].a; i >= 1; i--) {
    curr.b += c[i];
    if (curr.b < 0) break;
    max_r = min(max_r, i);
    if (!c[i]) {
      P p = mp[i];
      if (p.b > curr.b) {
        curr = p;
        r.push(curr);
      }
    }
  }
  #if DEBUG
  cout << "max_l: " << max_l << endl;
  cout << "max_r: " << max_r << endl;
  #endif
  if (max_l + 1 < max_r) {
    cout << -1 << endl;
  }
  else {
    int target = max_l;
    memset(vis, 0, sizeof vis);
    cout << target << endl;
    while (!l.empty()) {
      P p = l.top();
      l.pop();
      if (vis[id[p.a]]) continue;
      cout << id[p.a] << ' ';
      vis[id[p.a]] = 1;
    }
    while (!r.empty()) {
      P p = r.top();
      r.pop();
      if (vis[id[p.a]]) continue;
      cout << id[p.a] << ' ';
      vis[id[p.a]] = 1;
    }
    for (int i = 1; i <= m; i++) {
      if (vis[i]) continue;
      cout << i << ' ';
    }
    cout << endl;
  }
  return 0;
}

上一题