2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution

A - Odd Palindrome

水。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define N 110
 6 
 7 char s[N];
 8 
 9 inline bool work()
10 {
11     int len = strlen(s);
12     for (int i = 1; i < len; ++i)
13     {
14         if (s[i] == s[i - 1]) return false;
15     }
16     return true;
17 }
18 
19 int main()
20 {
21     while (scanf("%s", s) != EOF)
22     {
23         puts(work() ? "Odd." : "Or not.");
24     }
25     return 0;
26 }
View Code

 

B - Enlarging Enthusiasm

留坑。

 

C - Fear Factoring

题意:定义$F(n)$ 为 n的约数和  求 $S = \sum_{a <= n <= b}  F(n)$

思路:对于1-$\sqrt(b)$内的因数可以进行枚举。对于大于$\sqrt(b)$的因数,在枚举1-sqrt(b)的因数i的时候,a-b内的(a-1)/i, b/i是一段连续的数,通过求和公式即可得到

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 ll a,b;
 8 
 9 int main()
10 {
11     while(~scanf("%lld %lld", &a, &b))
12     {
13         if(a > b) swap(a, b);
14         ll tmp = sqrt(b);
15         ll ans = 0;
16         for(ll i = 1; i <= tmp; ++i)
17         {
18             ans += i * (b / i - (a - 1) / i);
19             ll tmp1 = max(tmp, (a - 1) / i);
20             ll tmp2 = max(tmp, b / i);
21             ans += (tmp2 - tmp1) * (tmp1 + tmp2 + 1) / 2;
22         }
23         printf("%lld\n", ans);
24     }
25     return 0;
26 }
View Code

 

D - Rainbow Roads

题意:彩虹:一条路径当中,相邻的两条边,权值都不同     好点:以某个点为端点的所有简单路径当中,都是彩虹。 求一棵树当中有多少个好点

思路:两种情况

1° DFS下去碰到相邻的两条边,那么这两条边的最上面的那个点上面的其他所有点都不是好点,这两条边最下面那个点的子树的所有点,都不是好点

2°以某个点为根的子树中,有两个直系儿子的边权相同,那么这两个儿子的子树的所有点都不是好点

DFS序  区间标记

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define N 50010
  6 
  7 struct node{
  8     int v;
  9     int c;
 10     inline node(){}
 11     inline node(int v,int c) :v(v),c(c){}
 12     inline bool operator < (const node &b) const
 13     {
 14         return c < b.c;
 15     }
 16 };
 17 
 18 int n;
 19 vector<node>G[N];
 20 int fa[N];
 21 int son[N];
 22 int ord[N];
 23 int dro[N];
 24 int arr[N];
 25 int cnt;
 26 
 27 inline void Init()
 28 {
 29     cnt = 0;
 30     memset(arr, 0, sizeof arr);
 31     for(int i = 1; i <= n; ++i)
 32     {
 33         G[i].clear();
 34     }
 35 }
 36 
 37 inline void DFS(int u,int pre)
 38 {
 39     fa[u] = pre;
 40     ord[u] = ++cnt;
 41     dro[cnt] = u;
 42     son[u] = 1;
 43     for(auto it : G[u])
 44     {
 45         int v = it.v;
 46         if(v == pre) continue;
 47         DFS(v, u);
 48         son[u] += son[v];
 49     }
 50 }
 51 
 52 int main()
 53 {
 54     while(~scanf("%d", &n))
 55     {
 56         Init();
 57         for(int i = 1; i < n; ++i)
 58         {
 59             int u, v, c;
 60             scanf("%d %d %d", &u, &v, &c);
 61             G[u].push_back(node(v, c));
 62             G[v].push_back(node(u, c));
 63         }
 64         DFS(1, -1);
 65         for(int i = 1; i <= n; ++i)
 66         {
 67             sort(G[i].begin(), G[i].end());
 68             int len = G[i].size();
 69             int it = 0;
 70             for(int j = it; j < len; j = it)
 71             {
 72                 ++it;
 73                 while(it < len && G[i][it].c == G[i][j].c)
 74                 {
 75                     ++it;
 76                 }
 77                 if(it > j + 1)
 78                 {
 79                     for(int k = j; k < it; ++k)
 80                     {
 81                         int v = G[i][k].v;
 82                         if(v == fa[i])
 83                         {
 84                             ++arr[ord[1]];
 85                             --arr[ord[i]];
 86                             ++arr[ord[i] + son[i]];
 87                         }
 88                         else
 89                         {
 90                             ++arr[ord[v]];
 91                             --arr[ord[v] + son[v]];
 92                         }
 93                     }
 94                 }
 95             }
 96         }
 97         for(int i = 1; i <= n; ++i)
 98         {
 99             arr[i] += arr[i - 1];
100         }
101         vector<int>vec;
102         for(int i = 1; i <= n; ++i)
103         {
104             if(arr[i] == 0)
105             {
106                 vec.push_back(dro[i]);
107             }
108         }
109         int len = vec.size();
110         sort(vec.begin(), vec.end());
111         printf("%d\n", len);
112         for(int i = 0; i < len; ++i)
113         {
114             printf("%d\n",vec[i]);
115         }
116     }
117     return 0;
118 }
View Code

 

 

E - Straight Shot

题意:一个机器人,给定初始速度,问从(0,0)到(0,x)。在这段路程上存在沿着y轴方向滑动的部分街道

思路:对v进行正交分解后,很容易发现vy=$\sum_{l <= i <= n }  (r - l) * vi$ 从而得到了vy,在进行计算vx,从而得到时间。

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 double x, v, vy;
 6 double l, r, vi, tmp;
 7 
 8 int n;
 9 
10 int main()
11 {
12     while(~scanf("%d %lf %lf", &n, &x, &v))
13     {
14         tmp = 0;
15         for(int i = 1; i <= n; ++i)
16         {
17             scanf("%lf %lf %lf", &l, &r, &vi);
18             tmp += (r - l) * vi;
19         }
20         vy = tmp / x;
21         if(fabs(vy) > v)
22         {
23             puts("Too hard");
24         }
25         else
26         {
27             double vx = sqrt(v * v - vy * vy);
28             double ans = x / vx;
29             printf("%.3f\n", ans);
30         }
31     }
32     return 0;
33 }
View Code

 

F - Distinct Distances

留坑。

 

G - Security Badge

留坑。

 

H - Avoiding Airports

留坑。

 

I - Long Long Strings

题意:有两个长度为$10_10$的DNA序列,刚开始相同,有两类操作,一种是添加,一种是删除,求两个DNA序列经过一系列操作后是否相同

思路:维护两个东西,一个是新添加的坐标,一个是在原序列中删除的坐标

新添加的话,那么在它之前添加的坐标大于等于它的都要后移一位

删除的话,如果是删除的新添加的,就直接删除,要注意新添加的坐标在它后面的都要前移一位

如果是在原序列中删除,要考虑删除的坐标是原来在它之前新添加的,要后移一位,还有在它之前的删除的都要加上

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 
 6 typedef pair <ll, char> plc;
 7 
 8 vector <ll> Del[2];
 9 vector <plc> Ins[2];
10 char s[10]; ll num; char c; 
11 
12 inline bool Dell(int vis, ll num) 
13 {
14     for (int i = 0, len = Ins[vis].size(); i < len; ++i) if (Ins[vis][i].first == num)
15     {
16         Ins[vis].erase(Ins[vis].begin() + i); 
17         for (auto &it : Ins[vis]) if (it.first >= num)
18             --it.first;
19         return true;
20     }
21     return false;  
22 } 
23 
24 inline void Delll(int vis)  
25 {
26     ll tmp = num; 
27     for (auto &it : Ins[vis]) 
28     {
29         if (num >= it.first) 
30             --tmp; 
31         else
32             --it.first;  
33     }
34     for (auto it : Del[vis])
35     {
36         if (it <= tmp)  
37             ++tmp;    
38         else
39             break;
40     }
41     num = tmp; 
42 }
43 
44 inline void work(int vis) 
45 {
46     Ins[vis].clear(); Del[vis].clear(); 
47     while (scanf("%s", s), s[0] != 'E') 
48     {
49         scanf("%lld", &num);
50         if (s[0] == 'I')
51         {
52             scanf(" %c", &c);
53             for (auto &it : Ins[vis]) if (it.first >= num)
54                 ++it.first;
55             Ins[vis].emplace_back(num, c);
56             for (int len = Ins[vis].size(), i = len - 1; i >= 1; --i) if (Ins[vis][i].first < Ins[vis][i - 1].first) 
57                 swap(Ins[vis][i], Ins[vis][i - 1]); 
58         }
59         else
60         {
61             if (Dell(vis, num)) continue;
62             Delll(vis);
63             Del[vis].emplace_back(num); 
64             for (int len = Del[vis].size(), i = len - 1; i >= 1; --i) if (Del[vis][i] < Del[vis][i - 1])
65                 swap(Del[vis][i], Del[vis][i - 1]);
66         }
67     }
68 }
69 
70 inline bool Com()
71 {
72     if (Ins[0].size() != Ins[1].size() || Del[0].size() != Del[1].size()) return false;
73     for (int i = 0, len = Ins[0].size(); i < len; ++i) if (Ins[0][i].first != Ins[1][i].first || Ins[0][i].second != Ins[1][i].second)
74         return false;
75     for (int i = 0, len = Del[0].size(); i < len; ++i) if (Del[0][i] != Del[1][i]) 
76         return false; 
77     return true;
78 }
79 
80 inline void Run() 
81 {
82     work(0); work(1);
83     puts(Com() ? "0" : "1");
84 }
85 
86 int main()
87 {
88     #ifdef LOCAL
89         freopen("Test.in", "r", stdin);
90     #endif
91 
92     Run(); 
93 
94     return 0; 
95 }
View Code

 

 

J - Grid Coloring

题意:给出一个n * m 的地图,上面有一些点已经涂色,如果已经涂了B 那么从左上角到这个点的矩形都是B 如果是R 那么从右下角的矩形都是R 有一些空点,求有多少种染色方案

思路:F[i][j][2] 表示 到第i行第j列这个点涂0(‘B’) 或者 涂1('R') 有多少种方案

如果这个点涂0 那么它左边都是已经确定的 转移的状态就是它下面那个点涂0的方案数+涂1的方案数

如果这个点涂1,那么它下面都是已经确定了,转移的状态就是它左边那个点涂0的方案数+涂1的方案数

注意本来就是0和1的情况

 1 #include <bits/stdc++.h> 
 2 using namespace std;
 3 
 4 #define N 50
 5 #define ll long long
 6 
 7 int n, m;
 8 char G[N][N];
 9 ll dp[N][N];
10 
11 inline bool Full(int x, int y, int vis)
12 {
13     if (!vis)
14     {
15         for (int i = 1; i <= x; ++i)
16             for (int j = 1; j <= y; ++j)
17             {
18                 if (G[i][j] == 'R')
19                     return false;
20                 G[i][j] = 'B';
21             }
22     } 
23     else
24     {
25         for (int i = x; i <= n; ++i)
26             for (int j = y; j <= m; ++j)
27             {
28                 if (G[i][j] == 'B')
29                     return false;
30                 G[i][j] = 'R';
31             }
32     }
33     return true;
34 }
35 
36 inline bool work()
37 {
38     for (int i = 1; i <= n; ++i)
39     {
40         for (int j = 1; j <= m; ++j)
41         {
42             if (G[i][j] == 'B')
43             {
44                 if (Full(i, j, 0) == false)
45                     return false;
46             }
47             else if (G[i][j] == 'R')
48             {
49                 if (Full(i, j, 1) == false)
50                     return false;
51             }
52         }
53     }
54     return true;
55 }
56 
57 inline void Run()
58 {
59     while (scanf("%d%d", &n, &m) != EOF)
60     {
61         for (int i = 1; i <= n; ++i) scanf("%s", G[i] + 1);
62         if (work() == false) 
63         {
64             puts("0");   
65             continue; 
66         }
67         memset(dp, 0, sizeof dp);
68         for (int i = 1; i <= n; ++i) dp[i][0] = 1;
69         for (int j = 1; j <= m; ++j) dp[n + 1][j] = 1;
70         for (int i = n; i >= 1; --i)
71         {
72             for (int j = 1; j <= m; ++j)
73             {
74                 if (G[i][j] == '.')
75                 {
76                     dp[i][j] = dp[i + 1][j] + dp[i][j - 1];
77                 }
78                 else if (G[i][j] == 'B')
79                     dp[i][j] = dp[i + 1][j];
80                 else
81                     dp[i][j] = dp[i][j - 1];
82             }
83         }
84         printf("%lld\n", dp[1][m]);
85     }
86 }
87 
88 int main()
89 {
90     #ifdef LOCAL
91         freopen("Test.in", "r", stdin);
92     #endif
93 
94     Run(); 
95 
96     return 0; 
97 }
View Code

 

 

K - Spinning Up Palindromes

留坑。

 

L - Delayed Work

水(暴力枚举人数)

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define INF 0x3f3f3f3f
 6 #define D 1000000
 7 
 8 double k, p, x;
 9 
10 int main()
11 {
12     while (scanf("%lf%lf%lf", &k, &p, &x) != EOF)
13     {
14         double ans = INF;
15         for (int i = 1; i <= D; ++i)
16         {
17             double day = (k * 1.0 / i);
18             ans = min(ans, x * i + p * day);
19         }
20         printf("%.3f\n", ans);
21     }
22     return 0;
23 }
View Code

 

M - Unsatisfying

留坑。

posted @ 2018-08-28 16:41  Dup4  阅读(503)  评论(0编辑  收藏  举报