2018-2019 ACM-ICPC, Asia Seoul Regional Contest

ProblemA Circuits

Solved.

题意:

有$n$个矩形,可以放两条平行与$x$轴的线,求怎么放置两条无线长的平行于$x$轴的线,使得他们与矩形相交个数最多

如果一个矩形同时与两条线相交,只算一次。

思路:

离散化后枚举一根线,另一根线用线段树维护,扫描线思想

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define N 400010
  5 int n;
  6 int b[N];
  7 int x[N], y[N];
  8 vector <int> in[N], out[N];
  9 int ans[N];
 10
 11 namespace SEG
 12 {
 13     struct node
 14     {
 15         int Max, lazy;
 16         node () {}
 17         node (int Max, int lazy) : Max(Max), lazy(lazy) {}
 18         void init() { Max = lazy = 0; }
 19         void add(int x)
 20         {
 21             Max += x;
 22             lazy += x;
 23         }
 24         node operator + (const node &other) const
 25         {
 26             node res; res.init();
 27             res.Max = max(Max, other.Max);
 28             return res;
 29         }
 30     }a[N << 2];
 31     void build(int id, int l, int r)
 32     {
 33         a[id].init();
 34         if (l == r)
 35             return;
 36         int mid = (l + r) >> 1;
 37         build(id << 1, l, mid);
 38         build(id << 1 | 1, mid + 1, r);
 39     }
 40     void pushdown(int id)
 41     {
 42         if (!a[id].lazy) return;
 43         a[id << 1].add(a[id].lazy);
 44         a[id << 1 | 1].add(a[id].lazy);
 45         a[id].lazy = 0;
 46     }
 47     void update(int id, int l, int r, int ql, int qr, int x)
 48     {
 49         if (l >= ql && r <= qr)
 50         {
 51             a[id].add(x);
 52             return;
 53         }
 54         int mid = (l + r) >> 1;
 55         pushdown(id);
 56         if (ql <= mid) update(id << 1, l, mid, ql, qr, x);
 57         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, x);
 58         a[id] = a[id << 1] + a[id << 1 | 1];
 59     }
 60     int query(int id, int l, int r, int pos)
 61     {
 62         if (l == r) return a[id].Max;
 63         int mid = (l + r) >> 1;
 64         pushdown(id);
 65         if (pos <= mid) return query(id << 1, l, mid, pos);
 66         else return query(id << 1 | 1, mid + 1, r, pos);
 67     }
 68 }
 69
 70 void Hash()
 71 {
 72     sort(b + 1, b + 1 + b[0]);
 73     b[0] = unique(b + 1, b + 1 + b[0]) - b - 1;
 74     for (int i = 1; i <= n; ++i) x[i] = lower_bound(b + 1, b + 1 + b[0], x[i]) - b;
 75     for (int i = 1; i <= n; ++i) y[i] = lower_bound(b + 1, b + 1 + b[0], y[i]) - b;
 76 }
 77
 78 int main()
 79 {
 80     while (scanf("%d", &n) != EOF)
 81     {
 82         b[0] = 0;
 83         for (int i = 1; i < N; ++i)
 84             in[i].clear(), out[i].clear();
 85         for (int i = 1, tmp; i <= n; ++i)
 86         {
 87             scanf("%d%d%d%d", &tmp, y + i, &tmp, x + i);
 88 //            cout << x[i] << " " << y[i] << endl;
 89             b[++b[0]] = x[i];
 90             b[++b[0]] = y[i];
 91         }
 92         Hash();
 93         SEG::build(1, 1, b[0]);
 94         for (int i = 1; i <= n; ++i)
 95         {
 96             in[x[i]].push_back(i);
 97             out[y[i]].push_back(i);
 98             SEG::update(1, 1, b[0], x[i], y[i], 1);
 99         }
100         int res = 0;
101         for (int i = 1; i <= b[0]; ++i)
102             ans[i] = SEG::query(1, 1, b[0], i);
103         for (int i = 1; i <= b[0]; ++i)
104         {
105             for (auto it : in[i])
106                 SEG::update(1, 1, b[0], x[it], y[it], -1);
107             res = max(res, ans[i] + SEG::a[1].Max);
108             for (auto it : out[i])
109                 SEG::update(1, 1, b[0], x[it], y[it], 1);
110         }
111         printf("%d\n", res);
112     }
113     return 0;
114 }

Problem D Go Latin

Solved.

按题意模拟。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int t;
 5 map <string, string> mp;
 6
 7 int main()
 8 {
 9     mp["a"] = "as";
10     mp["i"] = "ios";
11     mp["y"] = "ios";
12     mp["l"] = "les";
13     mp["n"] = "anes";
14     mp["ne"] = "anes";
15     mp["o"] = "os";
16     mp["r"] = "res";
17     mp["t"] = "tas";
18     mp["u"] = "us";
19     mp["v"] = "ves";
20     mp["w"] = "was";
21     ios::sync_with_stdio(false);
22     cin.tie(0); cout.tie(0);
23     cin >> t;
24     string s;
25     while (t--)
26     {
27         cin >> s;
28         int len = s.size();
29         string tmp = "";
30         tmp += s[len - 1];
31         if (mp.find(tmp) != mp.end())
32         {
33             s.erase(s.begin() + len - 1);
34             s += mp[tmp];
35         }
36         else
37         {
38             tmp = "";
39             tmp += s[len - 2];
40             tmp += s[len - 1];
41             if (mp.find(tmp) != mp.end())
42             {
43                 s.erase(s.begin() + len - 2, s.end());
44                 s += mp[tmp];
45             }
46             else
47                 s += "us";
48         }
49         cout << s << "\n";
50     }
51     return 0;
52 }

ProblemE LED

Upsolved.

题意:求一个分段函数的最小最大值

思路:

注意$v = 0$的时候,其余部分二分,贪心验证

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define ll long long
 5 #define N 300010
 6 struct node
 7 {
 8     ll v, l;
 9     void scan()
10     {
11         scanf("%lld%lld", &v, &l);
12         l *= 10ll;
13     }
14     bool operator < (const node &other) const { return v < other.v; }
15 }a[N];
16 int n;
17
18 bool check(ll x)
19 {
20     int i;
21     ll l1, l2;
22     for (i = 1; i <= n; ++i)
23     {
24         if (a[i].l > x)
25             break;
26     }
27     if (i > n) return true;
28     ll Max = 0, Min = (ll)1e11;
29     for (; i <= n; ++i)
30     {
31         Max = max(Max, a[i].l);
32         Min = min(Min, a[i].l);
33         if (Max - (Max + Min) / 2 > x)
34             break;
35         l1 = (Max + Min) / 2;
36     }
37     if (i > n) return true;
38     Max = 0, Min = (ll)1e11;
39     for (; i <= n; ++i)
40     {
41         Max = max(Max, a[i].l);
42         Min = min(Min, a[i].l);
43         if (Max - (Max + Min) / 2 > x)
44             break;
45         l2 = (Max + Min) / 2;
46     }
47     //cout << x << " " << l1 << " " << l2 << endl;
48     if (i <= n) return false;
49     return l2 >= l1;
50 }
51
52 int main()
53 {
54     while (scanf("%d", &n) != EOF)
55     {
56         for (int i = 1; i <= n; ++i) a[i].scan();
57         sort(a + 1, a + 1 + n);
58         ll base = 0;
59         int j = 0;
60         for (int i = 1; i <= n; ++i)
61         {
62             if (a[i].v == 0)
63                 base = max(base, a[i].l);
64             else
65                 a[++j] = a[i];
66         }
67         n = j;
68         ll l = 0, r = (ll)1e11, res = -1;
69         while (r - l >= 0)
70         {
71             ll mid = (l + r) >> 1;
72             if (check(mid))
73             {
74                 res = mid;
75                 r = mid - 1;
76             }
77             else
78                 l = mid + 1;
79         }
80         res = max(res, base);
81         ll x = res % 10;
82         res /= 10;
83         printf("%lld.%lld\n", res, x);
84     }
85     return 0;
86 }

ProblemF Parentheses

Upsolved.

题意:给出一个表达式,先判合法性,再判是否有括号冗余或者缺少。

思路:

直接判吧,数据里面有一个空行,不要多组读入。。。

vp的时候以为有(-b)这种东西,实际上没有。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define N 1000100
  5 char s[N];
  6 int id[N], len;
  7
  8 bool ok()
  9 {
 10     len = strlen(s + 1);
 11     for (int i = 1; i <= len; ++i)
 12     {
 13         if (isalpha(s[i]))
 14             id[i] = 0;
 15         else if (s[i] == ‘+‘ ||
 16                  s[i] == ‘-‘ ||
 17                  s[i] == ‘*‘ ||
 18                  s[i] == ‘/‘ ||
 19                  s[i] == ‘%‘)
 20                  id[i] = 1;
 21         else if (s[i] == ‘(‘)
 22             id[i] = 2;
 23         else
 24             id[i] = 3;
 25     }
 26     if (id[1] == 3 || id[len] == 2) return false;
 27     if (id[1] == 1 || id[len] == 1) return false;
 28     if (len == 1 && id[1] == 0)
 29         return true;
 30     for (int i = 2, x, y; i <= len; ++i)
 31     {
 32         x = id[i - 1], y = id[i];
 33         if (x == 0 && y == 0)
 34             return false;
 35         if (x == 1 && y == 1)
 36             return false;
 37         if (x == 1 && y == 3)
 38             return false;
 39         if (x == 2 && y == 1)
 40             return false;
 41         if (x == 2 && y == 3)
 42             return false;
 43         if (x == 3 && y == 2)
 44             return false;
 45         if (x == 3 && y == 0)
 46             return false;
 47         if (x == 0 && y == 2)
 48             return false;
 49     }
 50     int cnt = 0;
 51     for (int i = 1; i <= len; ++i)
 52     {
 53         if (id[i] == 2)
 54             ++cnt;
 55         else if (id[i] == 3)
 56         {
 57             if (cnt == 0)
 58                 return false;
 59             --cnt;
 60         }
 61     }
 62     return cnt == 0;
 63 }
 64
 65     // 0 alpha
 66     // 1 + - * / %
 67     // 2 (
 68     // 3 )
 69
 70 bool work()
 71 {
 72     if (len == 1) return true;
 73     int cnt = 0, sym = 0;
 74     for (int i = 1; i <= len; ++i)
 75         sym += (id[i] == 1);
 76     stack <int> sta;
 77     for (int i = 1; i <= len; ++i)
 78     {
 79         if (id[i] == 0)
 80             continue;
 81         else if (id[i] <= 2)
 82             sta.push(id[i]);
 83         else if (id[i] == 3)
 84         {
 85             int flag = 0;
 86             while (!sta.empty())
 87             {
 88                 int top = sta.top(); sta.pop();
 89                 if (top == 2)
 90                     break;
 91                 if (top == 1)
 92                     ++flag;
 93             }
 94             if (flag == 1) ++cnt;
 95             else
 96                 return false;
 97         }
 98     }
 99     return cnt == sym - 1;
100 }
101
102 int main()
103 {
104     gets(s + 1);
105     {
106         len = strlen(s + 1);
107         //if (len == 0) continue;
108         int now = 0;
109         for (int i = 1; i <= len; ++i)
110             if (s[i] != ‘ ‘)
111                 s[++now] = s[i];
112         s[++now] = 0;
113 //        cout << s + 1 << endl;
114         if (!ok()) puts("error");
115         else
116             puts(work() ? "proper" : "improper");
117     }
118     return 0;
119 }

ProblemK TV Show Game

Solved.

题意:$k$个灯, $n$个人, 每个人猜三个位置的灯的颜色, 要求构造出使得所有人都猜对两个或两个以上数量的灯的颜色的序列。

思路:枚举每个灯的状态, 2-SAT求解。

(2-SAT 不熟练啊 果然还是需要练一练)

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 const int maxn = 1e4 + 10;
 6
 7 struct node{
 8     int lamp1, lamp2, lamp3;
 9     int color1, color2, color3;
10 }arr[maxn];
11
12 int k, n;
13 int vis[maxn << 1];
14 vector<int>People[maxn], lamp[maxn];//R 0 B 1
15 int Stack[maxn], top;
16
17 void Init()
18 {
19     for(int i = 1; i < maxn; ++i) People[i].clear();
20     for(int i = 1; i < maxn; ++i) lamp[i].clear();
21 }
22
23 bool DFS(int u)
24 {
25     if(vis[u ^ 1]) return false;
26     if(vis[u]) return true;
27     vis[u] = 1;
28     Stack[top++] = u;
29     for(auto it : lamp[u])
30     {
31         for(auto v : People[it]) if(v != u)
32         {
33             if(!DFS(v ^ 1)) return false;
34         }
35     }
36     return true;
37 }
38
39 bool Twosat(int n)
40 {
41     memset(vis, 0, sizeof vis);
42     for(int i = 2; i <= n; i += 2)
43     {
44         if(vis[i] || vis[i ^ 1]) continue;
45         top = 0;
46         if(!DFS(i))
47         {
48             while(top) vis[Stack[--top]] = 0;
49             if(!DFS(i ^ 1)) return false;
50         }
51     }
52     return true;
53 }
54
55 int main()
56 {
57     while(~scanf("%d %d", &k, &n))
58     {
59         Init();
60         for(int i = 1; i <= n; ++i)
61         {
62             char a, b, c;
63             scanf("%d %c %d %c %d %c", &arr[i].lamp1, &a, &arr[i].lamp2, &b, &arr[i].lamp3, &c);
64
65             arr[i].color1 = (a == ‘B‘);
66             arr[i].color2 = (b == ‘B‘);
67             arr[i].color3 = (c == ‘B‘);
68
69             People[i].push_back(arr[i].lamp1 * 2 + (arr[i].color1 ^ 1));
70             lamp[arr[i].lamp1 * 2 + (arr[i].color1 ^ 1)].push_back(i);
71
72             People[i].push_back(arr[i].lamp2 * 2 + (arr[i].color2 ^ 1));
73             lamp[arr[i].lamp2 * 2 + (arr[i].color2 ^ 1)].push_back(i);
74
75             People[i].push_back(arr[i].lamp3 * 2 + (arr[i].color3 ^ 1));
76             lamp[arr[i].lamp3 * 2 + (arr[i].color3 ^ 1)].push_back(i);
77         }
78         if(Twosat(2 * k))
79         {
80             for(int i = 1; i <= k; ++i)
81             {
82                 if(vis[2 * i]) putchar(‘R‘);
83                 else putchar(‘B‘);
84             }
85             putchar(‘\n‘);
86         }
87         else puts("-1");
88     }
89     return 0;
90 }

ProblemL Working Plan

Solved.

题意:$m$个人, $n$天, 每个人一旦开始工作需要连续工作$w$天, 工作完w天后需要休息$h$天, 每天需要$d_i$个人, 每个人要求工作$W_i$天, 求方案。

思路:贪心, 优先使得剩余工作天数多的人工作。

  1 #include<bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 typedef long long ll;
  6
  7 const int maxn = 2e3 + 10;
  8
  9 struct node{
 10     int id;
 11     int st, ed;
 12     int workday;
 13     node(){}
 14     node(int id, int st, int ed, int workday): id(id), st(st), ed(ed), workday(workday){}
 15     bool operator < (const node  &other) const{
 16         if(st != other.st) return st > other.st;
 17         else return workday < other.workday;
 18     }
 19 };
 20
 21 bool cmp(node a, node b)
 22 {
 23     return a.workday < b.workday;
 24 }
 25
 26 int n, m,w, h;
 27 int W[maxn], d[maxn];
 28 priority_queue<node>q;
 29 priority_queue<int, vector<int>, greater<int> >Day;
 30 vector<int>ans[maxn];
 31 node Stack[maxn];
 32 int top;
 33
 34 void Init()
 35 {
 36     while(!q.empty()) q.pop();
 37     while(!Day.empty()) Day.pop();
 38     for(int i = 1; i <= m; ++i) ans[i].clear();
 39 }
 40
 41 int main()
 42 {
 43     while(~scanf("%d %d %d %d", &m, &n, &w, &h))
 44     {
 45         Init();
 46         for(int i = 1; i <= m; ++i) scanf("%d", W + i);
 47         for(int i = 1; i <= n; ++i) scanf("%d", d + i);
 48         for(int i = 1; i <= m; ++i) q.push(node(i, 0, 0, W[i]));
 49         bool flag = true;
 50         int cnt = 0;
 51         top = 0;
 52         for(int i = 1; i <= n; ++i)
 53         {
 54             while(!Day.empty())
 55             {
 56                 if(Day.top() < i) Day.pop();
 57                 else break;
 58             }
 59             int daysize = Day.size();
 60             if(daysize > d[i])
 61             {
 62                 flag = false;
 63                 break;
 64             }
 65             if(daysize == d[i]) continue;
 66             while(!q.empty())
 67             {
 68                 if(q.top().st <= i)
 69                 {
 70                     Stack[++top] = q.top();
 71                     q.pop();
 72                 }
 73                 else
 74                 {
 75                     break;
 76                 }
 77             }
 78             sort(Stack + 1, Stack + 1 + top, cmp);
 79             while(Day.size() < d[i])
 80             {
 81                 if(top < 1)
 82                 {
 83                     flag = false;
 84                     break;
 85                 }
 86                 node tmp = Stack[top--];
 87                 tmp.st = i;
 88                 ans[tmp.id].push_back(i);
 89                 tmp.st += w;
 90                 Day.push(tmp.st - 1);
 91                 tmp.st += h;
 92                 tmp.workday -= min(w, n - i + 1);
 93                 if(tmp.workday) q.push(tmp);
 94                 else cnt++;
 95             }
 96             if(Day.size() != d[i]) flag= false;
 97             if(flag == false) break;
 98         }
 99         if(cnt != m) flag = false;
100         if(flag)
101         {
102             puts("1");
103             for(int i = 1; i <= m; ++i) for(int j = 0, len = ans[i].size(); j < len; ++j) printf("%d%c", ans[i][j], " \n"[j == len - 1]);
104         }
105         else puts("-1");
106     }
107     return 0;
108 }

原文地址:https://www.cnblogs.com/Dup4/p/10462263.html

时间: 2024-11-02 08:36:46

2018-2019 ACM-ICPC, Asia Seoul Regional Contest的相关文章

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 (Gym - 102082)

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 A - Digits Are Not Just Characters 签到. B - Arithmetic Progressions 题意:从给定的集合中选出最多的数构成等差数列. 题解:数字排序后,设\(dp[i][j]\)表示等差数列最后一个数字为\(a[i]\),倒数第二个数字为\(a[j]\)的最大个数.然后对于每一位枚举 \(i\),\(lower\_bound()\)找有无合法的

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Krak&#243;w

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik's RectangleProblem B: What does the fox say?Problem C: Magical GCDProblem D: SubwayProblem E: EscapeProblem F: DraughtsProblem G: History courseProblem H: C

2018 ICPC Asia Jakarta Regional Contest

题目传送门 题号 A B C D E F G H I J K L 状态 Ο . . Ο . . . . Ο . . Ο Ο:当场 Ø:已补 .  :  待补 A. Edit Distance Thinking:kk pai爷 Code:kk 不能直接反转,比如"010101",直接反转后就变成"101010",右移一位,然后加个0就可以了. 所以要先统计01的数量,如果0大于1,就全变成1,1大于0,就全变成0(从数量上的改变就大于s/2了),相等的话,就看首位是0

2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings

As you might already know, space has always been a problem in ICPC Jakarta. To cope with this, ICPC Jakarta is planning to build two new buildings. These buildings should have a shape of a rectangle of the same size. Now, their problem is to find lan

2018-2019 ACM-ICPC, Asia Seoul Regional Contest K TV Show Game 2-sat

题目传送门 题意: 有n个人,k盏灯,灯有红蓝两种颜色,每个人都猜了三种灯的颜色,问如何安排灯的颜色,使得每个人猜的灯至少有两个是对的. 思路: 很容易想到2-sat,但是显然枚举每个人猜对的情况是不显示的,因为猜对两个和猜对三个两种情况就很难搞了.所以我们枚举每一个人猜的灯错的是哪一盏,如果某一盏错了,那么另外两盏就必须是对的,这样才符合条件. 我们用一个light的二维vector,保存:$灯的某种颜色,选这个颜色是属于选错的人$,再用一个二维vector名字叫people保存每个人的三种错

2019-2020 ICPC, Asia Jakarta Regional Contest C. Even Path

Pathfinding is a task of finding a route between two points. It often appears in many problems. For example, in a GPS navigation software where a driver can query for a suggested route, or in a robot motion planning where it should find a valid seque

2014 ACM/ICPC Asia Regional Guangzhou Online Wang Xifeng&#39;s Little Plot HDU5024

一道好枚举+模拟题目.转换思维视角 这道题是我做的,规模不大N<=100,以为正常DFS搜索,于是傻乎乎的写了起来.各种条件限制模拟过程 但仔细一分析发现对每个点进行全部八个方向的遍历100X100X100^8 .100X100个点,每个点在走的时候8中选择,TLE 于是改为另一个角度: 以符合要求的点为拐弯点,朝两个垂直的方向走,求出最远的距离.这样只要对每个点各个方向的长度知道,组合一下对应的就OK. 避免了每个点深搜. PS:搜索的时候x,y写反了,导致构图出现问题,以后用[dy][dx]

HDU 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ

hdu6206 Apple 2017 ACM/ICPC Asia Regional Qingdao Online

地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6206 题目: Apple Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 530    Accepted Submission(s): 172 Problem Description Apple is Taotao's favouri