2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) Solution

A - Airport Coffee

留坑。

 

B - Best Relay Team

枚举首棒

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define N 510
 6 #define INF 0x3f3f3f3f
 7 
 8 struct node
 9 {
10     string name;
11     double v1, v2;
12     inline void scan()
13     {
14         cin >> name >> v1 >> v2;
15     }
16     inline bool operator < (const node &r) const
17     {
18         return v2 < r.v2;
19     }
20 }arr[N];
21 
22 int n;
23 double Min;
24 string ans[4], tmpname[4];
25 
26 int main()
27 {
28     cin.tie(0);
29     cout.tie(0);
30     ios::sync_with_stdio(false);
31     cin >> n;
32     for (int i = 1; i <= n; ++i) arr[i].scan();
33     sort(arr + 1, arr + 1 + n);
34     Min = INF * 1.0;
35     for (int i = 1; i <= n; ++i)
36     {
37         double tmp = 0;
38         tmp += arr[i].v1;
39         tmpname[0] = arr[i].name;
40         for (int j = 1, cnt = 1; j <= n && cnt < 4; ++j)
41         {
42             if (i == j) continue;
43             tmp += arr[j].v2;
44             tmpname[cnt++] = arr[j].name;
45         }
46         if (tmp < Min)
47         {
48             Min = tmp;
49             for (int j = 0; j < 4; ++j) ans[j] = tmpname[j];
50         }
51     }
52     cout << setiosflags(ios::fixed) << setprecision(2) << Min << endl;
53     for (int i = 0; i < 4; ++i) cout << ans[i] << endl;
54     return 0;
55 }
View Code

 

C - Compass Card Sales

按题意模拟即可

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010 
  5 
  6 int n;
  7 set <int> se; 
  8 
  9 struct node 
 10 {
 11     int pos, v, pre, nx; 
 12     inline node() {}
 13     inline node(int _pos, int _v)
 14     {
 15         pos = _pos;
 16         v = _v;
 17         pre = -1, nx = -1;
 18     }
 19     inline bool operator < (const node &r) const
 20     {
 21         return v < r.v; 
 22     } 
 23 }R[N], G[N], B[N]; 
 24 
 25 struct DT
 26 {
 27     int r, g, b, id;  
 28     int id_r, id_g, id_b; 
 29     int v_r, v_g, v_b, v;  
 30     inline void scan()
 31     {
 32         scanf("%d%d%d%d", &r, &g, &b, &id);
 33         v = 0;
 34     }
 35     inline void Get()
 36     {
 37         int pre, nx; 
 38         v_r = 0; pre = R[id_r].pre, nx = R[id_r].nx;
 39         if (R[id_r].v != R[pre].v && R[id_r].v != R[nx].v)
 40         {
 41             v_r += (R[id_r].v - R[pre].v + 360) % 360;
 42             v_r += (R[nx].v - R[id_r].v+ 360) % 360; 
 43         }
 44         
 45         v_b = 0; pre = B[id_b].pre, nx = B[id_b].nx;
 46         if (B[id_b].v != B[pre].v && B[id_b].v != B[nx].v)
 47         {
 48             v_b += (B[id_b].v - B[pre].v + 360) % 360;
 49             v_b += (B[nx].v - B[id_b].v + 360) % 360;
 50         }
 51         
 52         v_g = 0; pre = G[id_g].pre, nx = G[id_g].nx;
 53         if (G[id_g].v != G[pre].v && G[id_g].v != G[nx].v)
 54         {
 55             v_g += (G[id_g].v - G[pre].v + 360) % 360;
 56             v_g += (G[nx].v - G[id_g].v + 360) % 360;
 57         }
 58         v = v_r + v_g + v_b;
 59     }
 60     inline void Remove()
 61     {
 62         int pre, nx;
 63         pre = R[id_r].pre, nx = R[id_r].nx;
 64         R[pre].nx = nx; R[nx].pre = pre;
 65         se.insert(R[pre].pos); se.insert(R[nx].pos);
 66         
 67         pre = G[id_g].pre, nx = G[id_g].nx;
 68         G[pre].nx = nx; G[nx].pre = pre;
 69         se.insert(G[pre].pos); se.insert(G[nx].pos);
 70         
 71         pre = B[id_b].pre, nx = B[id_b].nx;
 72         B[pre].nx = nx; B[nx].pre = pre;
 73         se.insert(B[pre].pos); se.insert(B[nx].pos);
 74     }
 75 }arr[N];
 76 
 77 struct Node
 78 {
 79     int id, v, pos;
 80     inline Node() {}
 81     inline Node(int pos, int id, int v) : pos(pos), id(id), v(v) {} 
 82     inline bool operator < (const Node &r) const 
 83     {
 84         return v > r.v || v == r.v && id < r.id;  
 85     }
 86 };
 87 
 88 bool used[N]; 
 89 int sum[N];
 90 priority_queue <Node> q;
 91 
 92 inline void Run()
 93 {
 94     while (scanf("%d", &n) != EOF)
 95     {
 96         while (!q.empty()) q.pop();
 97         memset(used, false, sizeof used);
 98         memset(sum, 0, sizeof sum); 
 99         for (int i = 1; i <= n; ++i) 
100         {
101             arr[i].scan();
102             R[i] = node(i, arr[i].r);
103             G[i] = node(i, arr[i].g);
104             B[i] = node(i, arr[i].b);
105         }
106         if (n == 1) 
107         {
108             printf("%d\n", arr[1].id); 
109             continue;
110         }
111         sort(R + 1, R + 1 + n);
112         sort(G + 1, G + 1 + n);
113         sort(B + 1, B + 1 + n);
114         for (int i = 1; i <= n; ++i) 
115         {
116             arr[R[i].pos].id_r = i; 
117             arr[G[i].pos].id_g = i;
118             arr[B[i].pos].id_b = i;
119             if (i == 1) 
120             {
121                 R[i].pre = n; G[i].pre = n; B[i].pre = n;
122                 R[i].nx = i + 1; G[i].nx = i + 1; B[i].nx = i + 1;
123             }
124             else if (i == n)
125             {
126                 R[i].pre = i - 1; G[i].pre = i - 1; B[i].pre = i - 1;
127                 R[i].nx = 1; G[i].nx = 1; B[i].nx = 1;
128             }
129             else
130             {
131                 R[i].pre = i - 1; G[i].pre = i - 1; B[i].pre = i - 1;
132                 R[i].nx = i + 1; G[i].nx = i + 1; B[i].nx = i + 1;
133             }
134         }
135         for (int i = 1; i <= n; ++i)
136         {
137             arr[i].Get(); sum[i] = arr[i].v;
138             q.emplace(i, arr[i].id, sum[i]);   
139         }
140         int cnt = 0;
141         while (cnt < n)
142         {
143             Node tmp = q.top(); q.pop();
144             if (used[tmp.pos] || sum[tmp.pos] != tmp.v) continue;
145             ++cnt; printf("%d\n", tmp.id); used[tmp.pos] = true;
146             se.clear(); arr[tmp.pos].Remove();
147             for (auto it : se)
148             {
149                 arr[it].Get();
150                 sum[it] = arr[it].v;
151                 q.emplace(it, arr[it].id, sum[it]);
152             }
153         }
154     }
155 }
156 
157 int main()
158 {
159     #ifdef LOCAL
160         freopen("Test.in", "r", stdin);
161     #endif
162 
163     Run(); 
164 
165     return 0; 
166 }
View Code

 

 

D - Distinctive Character

题意:给出n个玩家,有k个特征,用01串表示每个玩家有哪些特征,构造一个01串,和每个玩家对比有一个分数,有一个相同特征得一分,使得最大的分数最小

思路:可以将题意理解为有一个不同得一分,使得最小的分数最大。那么这时候可以用BFS跑一遍(类最短路?),然后找最大即可。

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn = 1 << 21;
 6 
 7 int n, k;
 8 char str[100];
 9 int vis[maxn];
10 int dis[maxn];
11 
12 inline void work(int x)
13 {
14     for(int i = k - 1; i >= 0; i--)
15     {
16         int u = 1 << i;
17         if(u & x) cout << "1";
18         else cout << "0";
19     }
20     cout << endl;
21 }
22 
23 int main()
24 {
25     while(~scanf("%d %d", &n, &k))
26     {
27         memset(vis, 0, sizeof vis);
28         memset(dis, -1, sizeof dis);
29         queue<int>q;
30         int tot = 1 << k;
31         for(int i = 1; i <= n; ++i)
32         {
33             scanf("%s", str);
34             int tmp = 0;
35             for(int i = 0; i < k; ++i)
36             {
37                 tmp = tmp * 2 + str[i] - '0';
38             }
39             vis[tmp] = 1;
40         }
41         for(int i = 0; i < tot; ++i)
42         {
43             if(vis[i] == 1)
44             {
45                 q.push(i);
46                 dis[i] = 0;
47             }
48         }
49         while(!q.empty())
50         {
51             int st = q.front();
52             q.pop();
53             for(int i = 0 ; i < k; ++i)
54             {
55                 int now = st ^ (1 << i);
56                 if(dis[now] == -1)
57                 {
58 //                    work(now);
59                     dis[now] = dis[st] + 1;
60                     q.push(now);
61                 }
62             }
63         }
64         int Max = -1;
65         int ans = -1;
66         for(int i = 0; i < tot; ++i)
67         {
68             if(dis[i] > Max)
69             {
70                 Max = dis[i];
71                 ans = i;
72             }
73         }
74         for(int i = k - 1; i >= 0; --i)
75         {
76             int u = 1 << i;
77             if(u & ans)
78             {
79                 printf("1");
80             }
81             else
82             {
83                 printf("0");
84             }
85         }
86         printf("\n");
87     }
88     return 0;
89 }
View Code

 

E - Emptying the Baltic

细胞(油田)。变种

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 #define N 510
 8 
 9 int n, m;
10 ll G[N][N];
11 ll val[N][N];
12 bool vis[N][N];
13 int dir[][2] = {1,0,0,1,-1,0,0,-1,1,1,1,-1,-1,-1,-1,1};
14 
15 struct node{
16     int x, y;
17     ll v;
18     inline node(){}
19     inline node(int x, int y, ll v) :x(x), y(y), v(v){}
20     inline bool operator < (const node & b)const
21     {
22         return v > b.v;
23     }    
24 };
25 
26 inline bool judge(int x, int y)
27 {
28     if(x > n || x < 1 || y < 1 || y > m || vis[x][y] || G[x][y] >= 0) return false;
29     else return true;
30 }
31 
32 int x, y;
33 
34 inline void BFS()
35 {
36     memset(val, 0, sizeof val);
37     memset(vis, false, sizeof vis);
38     priority_queue<node>q;
39     q.push(node(x, y, G[x][y]));
40     vis[x][y] = true;
41     val[x][y] = G[x][y];
42     while(!q.empty())
43     {
44         node st = q.top();
45         q.pop();
46         for(int i = 0 ; i < 8; ++i)
47         {
48             int dx = st.x + dir[i][0];
49             int dy = st.y + dir[i][1];
50             if(judge(dx, dy))
51             {
52                 ll tmp = max(G[dx][dy], st.v);
53                 val[dx][dy] = tmp;
54                 G[dx][dy] = tmp;
55                 q.push(node(dx, dy, tmp));
56                 vis[dx][dy] = true;
57             }
58         }
59     }
60 }
61 
62 int main()
63 {
64     while(~scanf("%d %d", &n, &m))
65     {
66         for(int i = 1; i <= n; ++i)
67         {
68             for(int j = 1; j <= m; ++j)
69             {
70                 scanf("%lld", &G[i][j]);
71                 if(G[i][j] >= 0)
72                 {
73                     G[i][j] = 0;
74                 }
75             }
76         }
77         scanf("%d %d", &x, &y);
78         BFS();
79         ll ans = 0;
80         for(int i = 1; i <= n; ++i)
81         {
82             for(int j = 1; j <= m; ++j)
83             {
84                 if(val[i][j] < 0)
85                 {
86                     ans += -val[i][j];
87                 }
88             }
89         }
90         printf("%lld\n", ans);
91     }    
92     return 0;
93 }
View Code

 

F - Fractal Tree

留坑。

 

G - Galactic Collegiate Programming Contest

题意:给出ICPC过题记录,给出id为1的队伍的排名

思路:先hash, 离散化,数据结构维护一下

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define N 100010
  6 #define ll long long
  7 
  8 const ll D = (ll)1e9;
  9 
 10 int n, m, q;
 11 ll arr[N], brr[N], sum[N], cnt;
 12 
 13 struct DT
 14 {
 15     int id;
 16     ll v;
 17     inline void scan()
 18     {
 19         scanf("%d%lld", &id, &v);
 20         v = sum[id] + D - v;
 21         sum[id] = v;
 22         arr[++cnt] = v;
 23     }
 24 }Data[N];
 25 
 26 inline void Init_Hash()
 27 {
 28     for (int i = 1; i <= cnt; ++i) brr[i] = arr[i];
 29     sort(brr + 1, brr + 1 + cnt);
 30     m = unique(brr + 1, brr + 1 + cnt) - brr - 1;
 31 }
 32 
 33 inline int Get(ll x)
 34 {
 35     return lower_bound(brr + 1, brr + 1 + m, x) - brr; 
 36 }
 37 
 38 struct node
 39 {
 40     int l, r;
 41     int sum;
 42     inline node() {}
 43     inline node(int l, int r, int sum) : l(l), r(r), sum(sum) {}
 44 }tree[N << 2];
 45 
 46 inline void pushup(int id)
 47 {
 48     tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
 49 }
 50 
 51 inline void build(int id, int l, int r)
 52 {
 53     tree[id] = node(l, r, 0);
 54     if (l == r) return;
 55     int mid = (l + r) >> 1;
 56     build(id << 1, l, mid);
 57     build(id << 1 | 1, mid + 1, r);
 58 }
 59 
 60 inline void update(int id, int pos, int val)
 61 {
 62     if (tree[id].l == tree[id].r) 
 63     {
 64         tree[id].sum += val;
 65         return;
 66     }
 67     int mid = (tree[id].l + tree[id].r) >> 1;
 68     if (pos <= mid) update(id << 1, pos, val);
 69     else update(id << 1 | 1, pos, val);
 70     pushup(id);
 71 }
 72 
 73 int anssum;
 74 
 75 inline void query(int id, int l, int r)
 76 {
 77     if (l > r) return;
 78     if (tree[id].l >= l && tree[id].r <= r)
 79     {
 80         anssum += tree[id].sum;
 81         return;
 82     }
 83     int mid = (tree[id].l + tree[id].r) >> 1;
 84     if (l <= mid) query(id << 1, l, r);
 85     if (r > mid) query(id << 1 | 1, l, r);
 86 }
 87 
 88 int main()
 89 {
 90     while (scanf("%d%d", &n, &q) != EOF)
 91     {
 92         int id; ll v;
 93         memset(sum, 0, sizeof sum); cnt = 0;
 94         for (int i = 1; i <= q; ++i) Data[i].scan();
 95         Init_Hash();
 96         memset(sum, 0, sizeof sum); build(1, 1, q);
 97         for (int i = 1; i <= q; ++i)
 98         {
 99             int id = Data[i].id; int pos = Get(Data[i].v);
100             if (sum[id]) update(1, sum[id], -1);
101             update(1, pos, 1); sum[id] = pos;  
102             anssum = 0; query(1, sum[1] + 1, q);
103             printf("%d\n", anssum + 1);
104         }
105     }
106     return 0;
107 }
View Code

 

H - Hubtown

留坑。

 

I - Import Spaghetti

题意:给出依赖关系,求最小的循环长度

思路:存图,枚举起点跑最短路

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define N 100010
  6 #define INF 0x3f3f3f3f
  7 
  8 unordered_map <string, int> mp;
  9 int cnt, n;
 10 string str[N], s;
 11 vector <string> ans;
 12 int Max, tot;
 13 
 14 inline int Get(string s)
 15 {
 16     if (mp.find(s) == mp.end()) mp[s] = ++cnt, str[cnt] = s;    
 17     return mp[s];
 18 }
 19 
 20 struct Edge
 21 {
 22     int to, nx;
 23     inline Edge() {}
 24     inline Edge(int to, int nx) : to(to), nx(nx) {}
 25 }edge[N << 2];
 26 
 27 int head[N], pos;
 28 
 29 inline void Init()
 30 {
 31     memset(head, -1, sizeof head);
 32     pos = 0; cnt =0; mp.clear(); ans.clear(); Max = INF; 
 33 }
 34 
 35 inline void addedge(int u, int v)
 36 {
 37     edge[++pos] = Edge(v, head[u]); head[u] = pos;
 38 }
 39 
 40 int dist[N];
 41 bool used[N];
 42 int pre[N];
 43 
 44 struct node
 45 {
 46     int to, w;
 47     inline node() {}
 48     inline node(int to, int w) : to(to), w(w) {}
 49     inline bool operator < (const node &r) const
 50     {
 51         return w > r.w;
 52     }
 53 };
 54 
 55 inline void Dijkstra(int root)
 56 {
 57     for (int i = 1; i <= n; ++i) dist[i] = INF, used[i] = false, pre[i] = -1;
 58     priority_queue <node> q; q.emplace(root, 0); 
 59     while (!q.empty())
 60     {
 61         int u = q.top().to, w = q.top().w; q.pop();
 62         used[u] = true;
 63         for (int it = head[u]; ~it; it = edge[it].nx)
 64         {
 65             int v = edge[it].to; 
 66             if (w + 1 < dist[v])
 67             {
 68                 pre[v] = u;
 69                 dist[v] = w + 1;
 70                 q.emplace(v, dist[v]);
 71             }
 72         }
 73     }
 74 }
 75 
 76 int main()
 77 {
 78     cin.tie(0); cout.tie(0);
 79     ios::sync_with_stdio(false);
 80     while (cin >> n)
 81     {
 82         Init();
 83 //        cout << "bug\n";
 84         for (int i = 1; i <= n; ++i)
 85         {
 86             cin >> s; Get(s);
 87 //            cout << s << endl;
 88         }
 89 //        cout << "bug\n";
 90         for (int i = 1; i <= n; ++i)
 91         {
 92             cin >> s >> tot;
 93             int u = Get(s);
 94             getline(cin, s);
 95             while (tot--)
 96             {
 97                 getline(cin, s);
 98 //                cout << s << endl;
 99                 stringstream ss;
100                 ss << s;
101                 while (ss >> s)
102                 {
103                     if (s == "import") continue;
104                     if (s.end()[-1] == ',') s.erase(s.end() - 1); 
105                     addedge(u, Get(s)); 
106                 }
107             }
108         }
109         for (int i = 1; i <= n; ++i)
110         {
111             Dijkstra(i);
112             if (dist[i] < Max)
113             {
114                 Max = dist[i];
115                 int it = pre[i];
116                 ans.clear(); 
117                 while (it != i)
118                 {
119                     ans.emplace_back(str[it]);
120                     it = pre[it];
121                 }
122                 ans.emplace_back(str[i]);
123             }    
124         }
125         if (Max == INF) 
126         {
127             cout << "SHIP IT" << endl;
128             continue;
129         }
130         reverse(ans.begin(), ans.end());
131         for (int i = 0, len = ans.size(); i < len; ++i) cout << ans[i] << " \n"[i == len -1];
132     }
133     return 0;
134 }
View Code

 

J - Judging Moose

签到

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int a, b;
 6 
 7 int main()
 8 {
 9     while (scanf("%d%d", &a, &b) != EOF)
10     {
11         if (a == 0 && b == 0)
12             puts("Not a moose");
13         else if (a == b)
14         {
15             printf("Even %d\n", a + b);
16         }
17         else
18             printf("Odd %d\n", max(a, b) * 2);
19     }
20     return 0;
21 }
View Code

 

K - Kayaking Trip

题意:给出三种人,每种人有力量值,然后有(人数总和)/2 条皮划艇,一条皮划艇的速度为 $v = c_i(s_1 + s_2)$, 求如何分配人员,使得速度最小的皮划艇速度最大

思路:二分答案,贪心check

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define N 100010
 6 #define INF 0x3f3f3f3f
 7 
 8 int n[3], s[3], m, tmp[3];
 9 int arr[N];
10 
11 struct node{
12     int x, y, v;
13     inline node() {}
14     inline node(int x, int y, int v) : x(x), y(y), v(v) {}
15     inline bool operator < (const node &b) const
16     {
17         return v < b.v;
18     }
19 }brr[10];
20 
21 int cnt;
22 
23 inline bool check(int mid)
24 {
25     for (int i = 0; i < 3; ++i) tmp[i] = n[i];
26     for (int i = 1; i <= m; ++i)
27     {
28         bool flag = false;
29         for (int j = 1; j <= cnt; ++j)
30         {
31             int x = brr[j].x, y = brr[j].y;
32             if (arr[i] * brr[j].v >= mid)
33             {
34                 if (x == y)
35                 {
36                     if (tmp[x] >= 2)
37                     {
38                         tmp[x] -= 2;
39                         flag = true;
40                         break;
41                     }
42                 }
43                 else
44                 {
45                     if (tmp[x] >= 1 && tmp[y] >= 1)
46                     {
47                         --tmp[x], --tmp[y];
48                         flag = true;
49                         break;
50                     }
51                 }
52             }
53         }
54         if (flag == false) return false;
55     }
56     return true;
57 }
58 
59 int main()
60 {
61     while (scanf("%d%d%d", &n[0], &n[1], &n[2]) != EOF)
62     {
63         m = n[0] + n[1] + n[2];
64         m >>= 1;
65         for (int i = 0; i < 3; ++i) scanf("%d", s + i);
66         for (int i = 1; i <= m; ++i) scanf("%d", arr + i);
67         cnt = 0;
68         for (int i = 0; i < 3; ++i)
69             for (int j = i; j < 3; ++j)
70                 brr[++cnt] = node(i, j, s[i] + s[j]);
71         sort(brr + 1, brr + 1 + cnt);
72         int l = 0, r = INF, ans;
73         while (r - l >= 0)
74         {
75             int mid = (l + r) >> 1;
76             if (check(mid))
77             {
78                 ans = mid;
79                 l = mid + 1;
80             }
81             else
82             {
83                 r = mid - 1;
84             }
85         }
86         printf("%d\n", ans);
87     }
88     return 0;    
89 }
View Code

 

posted @ 2018-08-30 17:01  Dup4  阅读(484)  评论(0编辑  收藏  举报