Codeforces Round #592 (Div. 2)

C - The Football Season

求gcd,遍历下p/w向下w个值即可,复杂度O(w)

Codeforces Round #592 (Div. 2)
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e3+7;
 5 const ll mod = 1e9 + 9;
 6 #define afdafafafdafaf y1;
 7 int ar[maxn], n;
 8  
 9  
10 void e_gcd(ll a, ll b, ll &gcd, ll &x, ll &y)
11 {
12     if (b==0){
13         x=1;
14         y=0;
15         gcd=a;
16     }else{
17         e_gcd(b, a%b, gcd, y, x);//注意要交换x和y 
18         y=y-x*(a/b);//有上面推导出来的公式
19         //x1 = y2(等式两边a的系数相同)
20         //y1 = x2 - (a / b) * y2 (等式两边b的系数相同) 
21     }
22 }
23 int main()
24 {
25     ll n,p,w,d;
26     scanf("%lld%lld", &n, &p);
27     scanf("%lld%lld", &w, &d);
28     if(n * w < p){
29         printf("-1\n");
30         return 0;
31     }
32     ll gcd, x, y;
33     e_gcd(w, d, gcd, x, y);
34     if(p % gcd != 0){
35         printf("-1\n");
36         return 0;
37     }
38     w /= gcd;
39     d /= gcd;
40     p /= gcd;
41     ll ins = p / w;
42     for(int i=0;i<=min(w, ins);i++){
43         if((p - (ins - i) * w) % d == 0){
44             x = ins - i;
45             y = (p - (ins - i) * w) / d;
46             break;
47         }
48     }
49     if(x >= 0 && y >= 0 && n - x - y >= 0){
50         printf("%lld %lld %lld\n", x, y, n - x - y);
51     }
52     else printf("-1\n");
53     return 0;
54 }
View Code

 

D - Paint the Tree

初步分析如果出现度大于等于3的点,没有配色方案,那么树一定是一条链,从链的一头开始遍历,dp即可

no[u].a[i][j]值得是u节点涂第i种颜色,他的子节点涂第j种颜色需要的最小花费,dp即可,过程略微繁琐

Codeforces Round #592 (Div. 2)
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int maxn = 1e5+7;
  5 const ll mod = 1e9 + 9;
  6 #define afdafafafdafaf y1;
  7 int ar[maxn], n;
  8  
  9 struct node{
 10     ll a[4][4];
 11 }no[maxn];
 12 int arr[4][maxn];
 13 vector<int> g[maxn];
 14 node dfs(int u, int pre){
 15     node nou;
 16     memset(nou.a, 0, sizeof(nou.a));
 17     for(int v : g[u]){
 18         if(v == pre)continue;
 19         node mid = dfs(v, u);
 20         for(int i=1;i<=3;i++){
 21             for(int j=1;j<=3;j++){
 22                 if(i != j)nou.a[i][j] += mid.a[i][j];
 23             }
 24         }
 25     }
 26     memset(no[u].a, 0, sizeof(no[u].a));
 27     no[u].a[1][2] = arr[1][u] + nou.a[2][3];
 28     no[u].a[1][3] = arr[1][u] + nou.a[3][2];
 29     no[u].a[2][1] = arr[2][u] + nou.a[1][3];
 30     no[u].a[2][3] = arr[2][u] + nou.a[3][1];
 31     no[u].a[3][1] = arr[3][u] + nou.a[1][2];
 32     no[u].a[3][2] = arr[3][u] + nou.a[2][1];
 33     return no[u];
 34 }
 35 int in[maxn], av[maxn];
 36 void dfs2(int u, int pre, int col, ll val, int pre_col){
 37     av[u] = col;
 38     if(in[u] == 1 && pre != 0){
 39         //assert(val == arr[col][u]);
 40     }
 41     for(int v : g[u]){
 42         if(v==pre)continue;
 43         ll mn = 1e18;
 44         int ins = 0;
 45         for(int j=1;j<=3;j++){
 46             if(col != j){
 47                 if(mn > no[u].a[col][j] && j != pre_col){
 48                     mn = no[u].a[col][j];
 49                     ins = j;
 50                 }
 51             }
 52         }
 53         //assert(val == mn);
 54         dfs2(v, u, ins, val - arr[col][u], col);
 55     }
 56 }
 57 int main()
 58 {
 59     scanf("%d", &n);
 60     for(int i=1;i<=3;i++){
 61         for(int j=1;j<=n;j++)scanf("%d", &arr[i][j]);
 62     }
 63     for(int i=1;i<n;i++){
 64         int a,b;scanf("%d%d", &a, &b);
 65         g[a].push_back(b);
 66         g[b].push_back(a);
 67         in[a]++;
 68         in[b]++;
 69     }
 70     for(int i=1;i<=n;i++){
 71         if(in[i] >= 3){
 72             printf("-1\n");
 73             return 0;
 74         }
 75     }
 76     int be = 0;
 77     int xx = 0;
 78     for(int i=1;i<=n;i++){
 79         if(in[i] == 1){
 80             be = i;
 81             xx++;
 82         }
 83         else{
 84             assert(in[i] == 2);
 85         }
 86     }
 87     assert(xx == 2);
 88     node mid = dfs(be, 0);
 89     ll ans = 1e18, ins = 0;
 90     for(int i=1;i<=3;i++){
 91         for(int j=1;j<=3;j++){
 92             if(i != j){
 93                 if(ans >= mid.a[i][j]){
 94                     ans = mid.a[i][j];
 95                     ins = i;
 96                 }
 97             }
 98         }
 99     }
100     dfs2(be, 0, ins, ans, -1);
101     printf("%lld\n", ans);
102     for(int i=1;i<=n;i++)printf("%d%c", av[i], i==n ? '\n' : ' ');
103  
104     return 0;
105 }
View Code

 

E - Minimizing Difference

看这个有序列里两个最值的数量,以此更新更小长度的最值即可,利用multiset来写,代码简洁很多

Codeforces Round #592 (Div. 2)
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5+7;
 5 const ll mod = 1e9 + 9;
 6 #define afdafafafdafaf y1;
 7 int ar[maxn], n;
 8  
 9 ll k;
10 int main()
11 {
12     scanf("%d%lld", &n, &k);
13     multiset<ll> s;
14     for(int i = 1; i <= n; i++){
15         scanf("%d", ar + i);
16         s.insert(ar[i]);
17     }
18     ll be = * s.begin();
19     auto it = s.end();
20     it--;
21     ll en = *it;
22     ll be_ins = s.count(be), en_ins = s.count(en);
23     ll ans = 0;
24     s.erase(be);
25     s.erase(en);
26     while(be < en){
27         if(s.size() == 0){
28             be = min(en, be + k / min(be_ins, en_ins));
29             break;
30         }
31         it = s.begin();
32         ll new_be = *it;
33         it = s.end();
34         it--;
35         ll new_en = *it;
36         if(be_ins < en_ins){
37             if(k > be_ins * (new_be - be)){
38                 k -= be_ins * (new_be - be);
39                 be = new_be;
40                 be_ins += s.count(be);
41                 s.erase(be);
42             }
43             else{
44                 be = min(en, be + k / be_ins);
45                 break;
46             }
47         }
48         else{
49             if(k > en_ins * (en - new_en)){
50                 k -= en_ins * (en - new_en);
51                 en = new_en;
52                 en_ins += s.count(en);
53                 s.erase(en);
54             }
55             else{
56                 en = max(be, en - k / en_ins);
57                 break;
58             }
59         }
60     }
61     ans = en - be;
62     printf("%lld\n", max(0LL, ans));
63     return 0;
64 }
View Code

 

上一篇:单片机:按秒计时 进入程序自动开始计时 K2暂停 K1继续 K3重新开始


下一篇:Codeforces Round #592 (Div. 2)