• 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
    ", 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
    ", 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("
    ");
    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
    ", 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
    ", 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
    ";
     84         for (int i = 1; i <= n; ++i)
     85         {
     86             cin >> s; Get(s);
     87 //            cout << s << endl;
     88         }
     89 //        cout << "bug
    ";
     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] << " 
    "[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
    ", a + b);
    16         }
    17         else
    18             printf("Odd %d
    ", 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
    ", ans);
    87     }
    88     return 0;    
    89 }
    View Code
  • 相关阅读:
    appium启动android和iOS真机
    文本编辑器Sublime Text 3 -mac版简体中文汉化教程
    Navicat Premium Mac 安装
    mac下安装jmeter
    Pycharm 配置git
    mac下jdk安装配置
    WebDriverAgentRunner安装成功后build的常见报错
    WebDriverAgent入门篇-安装和使用
    macOS升级
    Bash on windows从14.0升级到ubuntu16.04
  • 原文地址:https://www.cnblogs.com/Dup4/p/9561271.html
Copyright © 2020-2023  润新知