ACM-ICPC 2018 南京赛区网络预赛 Solution

A. An Olympian Math Problem

cout << n - 1 << endl;

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 
 6 int t; 
 7 ll n;
 8 
 9 inline void Run() 
10 {
11     scanf("%d", &t);
12     while (t--)
13     {
14         scanf("%lld", &n);
15         printf("%lld\n", n - 1);
16     }
17 }
18 
19 int main()
20 {
21     #ifdef LOCAL
22         freopen("Test.in", "r", stdin);
23     #endif
24 
25     Run(); 
26 
27     return 0; 
28 }
View Code

B. The writing on the wall

题意:给出n * m的矩形,找出有多少个子矩形不包含黑块

思路:枚举每一个当右下角的情况,那么情况总数就是黑块构成的边界里面的格子数量,优先队列优化

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 100010
 6 #define M 110
 7 
 8 int t, n, m, k; 
 9 int G[N][M];
10 int low[M]; 
11 
12 struct node
13 {
14     ll h, num;
15     inline node() {}
16     inline node(ll h, ll num) : h(h), num(num) {}
17     inline bool operator < (const node &r) const
18     {
19         return h < r.h;  
20     }
21 };
22 
23 priority_queue <node> q;
24 
25 int main()
26 {
27 #ifdef LOCAL_JUDGE
28     freopen("Text.txt", "r", stdin);
29 #endif // LOCAL_JUDGE
30     scanf("%d", &t);
31     for (int kase = 1; kase <= t; ++kase)
32     {
33         printf("Case #%d: ", kase); 
34         memset(G, 0, sizeof G);
35         memset(low, 0, sizeof low); 
36         while (!q.empty()) q.pop();
37         scanf("%d%d%d", &n, &m, &k);
38         for (int i = 1, x, y; i <= k; ++i)
39         {
40             scanf("%d%d", &x, &y);
41             G[x][y] = 1;
42         }
43         ll ans = 0, sum = 0;
44         for (int i = 1; i <= n; ++i)
45         {
46             for (int j = 1; j <= m; ++j)
47             {
48                 //if (i % 1000 == 0) cout << i << endl;
49                 if (G[i][j] == 1)
50                 {
51                     while (!q.empty()) q.pop();
52                     sum = 0;
53                     low[j] = i;
54                     continue;
55                 }
56                 if (j == 1)
57                 {
58                     while (!q.empty()) q.pop();
59                     sum = 0;
60                 }                
61                 ll H = i - low[j];
62                 ll num = 1;
63                 while (!q.empty() && q.top().h > H)
64                 {
65                     num += q.top().num;
66                     sum -= q.top().h * q.top().num;
67                     q.pop();
68                 }
69                 sum += num * H;
70                 ans += sum;
71                 q.emplace(H, num);
72             }
73         }
74         printf("%lld\n", ans);
75     }
76     return 0;
77 }
View Code

 C. GDY

留坑。

 D. Jerome's House

留坑。

 E. AC Challenge

题意:有n道题目,每次提交得到分数$t * a_i + b_i$ 有一些题目的提交必须要某些题目提交之后才能提交,求最后获得的最大分数

思路:记忆化搜索,二进制标记状态

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 ll dp[1 << 20];
 8 
 9 int n;
10 
11 struct node {
12     ll ai, bi;
13     int state;
14     inline node(){}
15     inline node(ll ai, ll bi, int state):ai(ai),bi(bi), state(state){}
16 }arr[30];
17 
18 inline ll DFS(int t, int S)
19 {
20     if (t > n) return 0;
21     if (dp[S] != -1) return dp[S];
22     ll res = 0;
23     for (int i = 0; i < n; ++i)
24     {
25         int tmp = 1 << i;
26         if ((tmp & S) == 0)
27         {
28             if ((S & arr[i].state) != arr[i].state) continue;
29             res = max(res, t * arr[i].ai + arr[i].bi + DFS(t + 1, (S | tmp)));
30         }
31     }
32     dp[S] = res;
33     return res;
34 }
35 
36 inline void RUN()
37 {
38     while (~scanf("%d", &n))
39     {
40         memset(dp, -1, sizeof dp);
41         for (int i = 0; i < n; ++i)
42         {
43             int m;
44             int S = 0;
45             scanf("%lld %lld %d", &arr[i].ai, &arr[i].bi, &m);
46             while (m--)
47             {
48                 int tmp = 0;
49                 scanf("%d", &tmp);
50                 S += (1 << (tmp - 1));
51             }
52             arr[i].state = S;
53         }
54         ll ans = DFS(1, 0);
55         printf("%lld\n", ans);
56     }
57 }
58 
59 int main()
60 {
61 #ifdef LOCAL_JUDGE
62     freopen("Text.txt", "r", stdin);
63 #endif // LOCAL_JUDGE
64 
65     RUN();
66 
67 #ifdef LOCAL_JUDGE
68     fclose(stdin);
69 #endif // LOCAL_JUDGE
70 
71     return 0;
72 }
View Code

 F. An Easy Problem On The Trees

留坑。

 G. Lpl and Energy-saving Lamps

留坑。

 H. Set

留坑。

 I. Skr

留坑。

 J. Sum

题意:定义$F[n] = 有多少个n = ab$ a 和 b 都不能是平方数的倍数 1 除外 求 $\sum_{i = 1} ^ {i = n} F[n]$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long ll;
 5 const int maxn = 2e7 + 5;
 6 
 7 int n;
 8 int tot;
 9 int isprime[maxn];
10 int prime[maxn];
11 int a[maxn];
12 int ans[maxn];
13 
14 inline void Init_prime()
15 {
16     tot = 1;
17     prime[1] = 1;
18     a[1] = 1;
19     ans[1] = 1;
20     for (register int i = 2; i < maxn; ++i)
21     {
22         a[i] = 1;
23         if (!isprime[i])
24         {
25             prime[tot++] = i;
26             
27         }
28         for (register int j = 1; j < tot && i * prime[j] < maxn; ++j)
29         {
30             isprime[i * prime[j]] = 1;
31             if (!(i % prime[j]))
32             {
33                 break;
34             }
35         }
36     }
37     for (register int i = 1; i < tot; ++i)
38     {
39         for (register int j = 1; j * prime[i] < maxn; ++j)
40         {
41             a[j * prime[i]] <<= 1;
42         }
43         if (prime[i] > maxn / prime[i]) continue;
44         for (register int j = 1; j * prime[i] * prime[i] < maxn; ++j)
45         {
46             if (j % prime[i] == 0)
47             {
48                 a[j * prime[i] * prime[i]] = 0;
49             }
50             a[j * prime[i] * prime[i]] >>= 1;
51         }
52     }
53     for (register int i = 1; i < maxn; ++i)
54     {
55         ans[i] = ans[i - 1] + a[i];
56     }
57 }
58 
59 int main()
60 {
61     Init_prime();
62     int t;
63     //cout << tot << endl;
64     scanf("%d", &t);
65     while (t--)
66     {
67         scanf("%d", &n);
68         printf("%d\n", ans[n]);
69     }
70     return 0;
71 }
View Code

 K. The Great Nim Game

留坑。

 L. Magical Girl Haze

题意:有n个城市,m条边,可以令k条路权值为0,求1 - n 的最短路

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 #define ll long long
  6 #define INFLL 0x3f3f3f3f3f3f3f3f
  7 
  8 struct Edge
  9 {
 10     int to, nx; ll w;
 11     inline Edge() {}
 12     inline Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
 13 }edge[N << 1];
 14 
 15 int head[N], pos;
 16 
 17 inline void Init()
 18 {
 19     memset(head, -1, sizeof head);
 20     pos = 0;
 21 }
 22 
 23 inline void addedge(int u, int v, ll w)
 24 {
 25     edge[++pos] = Edge(v, head[u], w); head[u] = pos;
 26 }
 27 
 28 struct node
 29 {
 30     int to, p; ll w;
 31     inline node() {}
 32     inline node(int to, int p, ll w) : to(to), p(p), w(w) {}
 33     inline bool operator < (const node &r) const
 34     {
 35         return w > r.w;
 36     }
 37 };
 38 
 39 ll dist[N][20];
 40 bool used[N][20];
 41 int t, n, m, k;
 42 
 43 inline void Dijkstra()
 44 {
 45     for (int i = 1; i <= n; ++i) for (int j = 0; j <= k; ++j) dist[i][j] = INFLL, used[i][j] = false;
 46     priority_queue <node> q; q.emplace(1, 0, 0); dist[1][0] = 0;
 47     while (!q.empty())
 48     {
 49         int u = q.top().to;
 50         int p = q.top().p;
 51         ll w = q.top().w;
 52         //cout << w << endl;
 53         q.pop();
 54         if (used[u][p]) continue;
 55         used[u][p] = true;
 56         dist[u][p] = w;
 57         for (int i = head[u]; ~i; i = edge[i].nx)
 58         {
 59             int v = edge[i].to;
 60             ll c = edge[i].w;
 61             if (dist[u][p] + c < dist[v][p])
 62             {
 63                 dist[v][p] = dist[u][p] + c;
 64                 q.emplace(v, p, dist[v][p]);
 65             }
 66             if (p + 1 <= k && dist[u][p] < dist[v][p + 1])
 67             {
 68                 dist[v][p + 1] = dist[u][p];
 69                 q.emplace(v, p + 1, dist[v][p + 1]);
 70             }
 71         }
 72     }
 73 }
 74 
 75 
 76 inline void Run()
 77 {
 78     scanf("%d", &t);
 79     while (t--)
 80     {
 81         Init();
 82         scanf("%d%d%d", &n, &m, &k);
 83         int u, v; ll w;
 84         for (int i = 1; i <= m; ++i)
 85         {
 86             scanf("%d%d%lld", &u, &v, &w);
 87             addedge(u, v, w);
 88         }
 89         Dijkstra();
 90         ll ans = dist[n][k];
 91         printf("%lld\n", ans);
 92     }
 93 }
 94 int main()
 95 {
 96     #ifdef LOCAL
 97         freopen("Test.in", "r", stdin);
 98     #endif
 99 
100     Run(); 
101 
102     return 0; 
103 }
View Code

猜你喜欢

转载自www.cnblogs.com/Dup4/p/9570883.html