codeforces #592 div2 ABCDEG

A. Pens and Pencils

Description

小明有一个笔盒,笔盒可以装钢笔和铅笔,钢笔写作业,铅笔考试。

每支钢笔可以写c份作业,每支铅笔可以做d份考试。

现在有a份作业,b场考试。

给定笔盒容量,问如何放笔能满足考试和作业。

Solution

签到水题

 1 #include <algorithm>
 2 #include <cctype>
 3 #include <cmath>
 4 #include <cstdio>
 5 #include <cstdlib>
 6 #include <cstring>
 7 #include <iostream>
 8 #include <map>
 9 #include <numeric>
10 #include <queue>
11 #include <set>
12 #include <stack>
13 #if __cplusplus >= 201103L
14 #include <unordered_map>
15 #include <unordered_set>
16 #endif
17 #include <vector>
18 #define lson rt << 1, l, mid
19 #define rson rt << 1 | 1, mid + 1, r
20 #define LONG_LONG_MAX 9223372036854775807LL
21 #define pblank putchar(' ')
22 #define ll LL
23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
24 using namespace std;
25 typedef long long ll;
26 typedef long double ld;
27 typedef unsigned long long ull;
28 typedef pair<int, int> P;
29 int n, m, k;
30 const int maxn = 1e5 + 10;
31 template <class T>
32 inline T read()
33 {
34     int f = 1;
35     T ret = 0;
36     char ch = getchar();
37     while (!isdigit(ch))
38     {
39         if (ch == '-')
40             f = -1;
41         ch = getchar();
42     }
43     while (isdigit(ch))
44     {
45         ret = (ret << 1) + (ret << 3) + ch - '0';
46         ch = getchar();
47     }
48     ret *= f;
49     return ret;
50 }
51 template <class T>
52 inline void write(T n)
53 {
54     if (n < 0)
55     {
56         putchar('-');
57         n = -n;
58     }
59     if (n >= 10)
60     {
61         write(n / 10);
62     }
63     putchar(n % 10 + '0');
64 }
65 template <class T>
66 inline void writeln(const T &n)
67 {
68     write(n);
69     puts("");
70 }
71 int main(int argc, char const *argv[])
72 {
73 #ifndef ONLINE_JUDGE
74     freopen("in.txt", "r", stdin);
75     // freopen("out.txt", "w", stdout);
76 #endif
77     int t = read<int>();
78     while (t--)
79     {
80         int a = read<int>(), b = read<int>(), c = read<int>(), d = read<int>();
81         k = read<int>();
82         int x = a / c, y = b / d;
83         a % c ? ++x : 0;
84         b % d ? ++y : 0;
85         if (x + y <= k)
86             write(x), pblank, writeln(y);
87         else
88             puts("-1");
89     }
90     return 0;
91 }
View Code

 

B. Rooms and Staircases

Description

 

 

小明有一栋两层楼别墅,每层有n个房间,有一些楼梯可以直通楼上楼下对应房间,没有楼梯则不能上下楼

小明可以从任意位置开始走,但他不愿意经过一间房间大于1次,

问小明最多经过多少房间

Solution

找到最左和最右的楼梯,如果没有楼梯$res=n$

否则$res=max(2(n-l+1),2r)$

  1 #include <algorithm>
  2 #include <cctype>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <map>
  9 #include <numeric>
 10 #include <queue>
 11 #include <set>
 12 #include <stack>
 13 #if __cplusplus >= 201103L
 14 #include <unordered_map>
 15 #include <unordered_set>
 16 #endif
 17 #include <vector>
 18 #define lson rt << 1, l, mid
 19 #define rson rt << 1 | 1, mid + 1, r
 20 #define LONG_LONG_MAX 9223372036854775807LL
 21 #define pblank putchar(' ')
 22 #define ll LL
 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
 24 using namespace std;
 25 typedef long long ll;
 26 typedef long double ld;
 27 typedef unsigned long long ull;
 28 typedef pair<int, int> P;
 29 int n, m, k;
 30 const int maxn = 1e5 + 10;
 31 template <class T>
 32 inline T read()
 33 {
 34     int f = 1;
 35     T ret = 0;
 36     char ch = getchar();
 37     while (!isdigit(ch))
 38     {
 39         if (ch == '-')
 40             f = -1;
 41         ch = getchar();
 42     }
 43     while (isdigit(ch))
 44     {
 45         ret = (ret << 1) + (ret << 3) + ch - '0';
 46         ch = getchar();
 47     }
 48     ret *= f;
 49     return ret;
 50 }
 51 template <class T>
 52 inline void write(T n)
 53 {
 54     if (n < 0)
 55     {
 56         putchar('-');
 57         n = -n;
 58     }
 59     if (n >= 10)
 60     {
 61         write(n / 10);
 62     }
 63     putchar(n % 10 + '0');
 64 }
 65 template <class T>
 66 inline void writeln(const T &n)
 67 {
 68     write(n);
 69     puts("");
 70 }
 71 int mp[2][1010];
 72 int vis[2][1010];
 73 int cur;
 74 inline int judge(int x, int y)
 75 {
 76     if (x >= 0 && x <= 1 && y && y <= n && !vis[x][y])
 77         return 1;
 78     return 0;
 79 }
 80 void dfs(int x, int y)
 81 {
 82     vis[x][y] = 1;
 83     ++cur;
 84 }
 85 int main(int argc, char const *argv[])
 86 {
 87 #ifndef ONLINE_JUDGE
 88     freopen("in.txt", "r", stdin);
 89     // freopen("out.txt", "w", stdout);
 90 #endif
 91     int t = read<int>();
 92     while (t--)
 93     {
 94         n = read<int>();
 95         for (int i = 1; i <= n; i++)
 96             mp[0][i] = mp[1][i] = getchar() - '0', vis[0][i] = vis[1][i] = 0;
 97         getchar();
 98         int res = 0, pl = 0, pr = 0;
 99         for (int i = 1; i <= n; i++)
100             if (mp[0][i] == 1)
101                 pl = i;
102         for (int i = n; i >= 1; i--)
103             if (mp[0][i] == 1)
104                 pr = i;
105         if (!pl)
106             res = n;
107         else
108             res = max(pl * 2, (n - pr + 1) * 2);
109         writeln(res);
110     }
111     return 0;
112 }
View Code

 

C. The Football Season

Description

给出$n,p,w,d,w \gt d$,求一组$x,y,z$满足$x+y+z \leq n,x*w+y*d \eq p$

Solution

看到题一眼以为是扩展欧几里得,但是自己菜没把条件罗列清楚。

赛后看题解。

假如有满足$x*w+y*d=p$存在,那么$(x+d)*w+(y-w)*d=p$依然成立

由于我们要求$x+y+z \ leq n$,那么我们可以求$x+y$最小的一组解

由上述条件可知,对于y值肯定是得小于w,因为只要$y \geq w$,我们都可以在让y减去w,并且让x上加上d,使等式成立。

且d<w,那么这样的$x+d+y-w \ lt x+y $,更优。

并且w数据范围在1e5,可以O(n)扫一遍出结果。

 1 #include <algorithm>
 2 #include <cctype>
 3 #include <cmath>
 4 #include <cstdio>
 5 #include <cstdlib>
 6 #include <cstring>
 7 #include <iostream>
 8 #include <map>
 9 #include <numeric>
10 #include <queue>
11 #include <set>
12 #include <stack>
13 #if __cplusplus >= 201103L
14 #include <unordered_map>
15 #include <unordered_set>
16 #endif
17 #include <vector>
18 #define lson rt << 1, l, mid
19 #define rson rt << 1 | 1, mid + 1, r
20 #define LONG_LONG_MAX 9223372036854775807LL
21 #define pblank putchar(' ')
22 #define ll LL
23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
24 using namespace std;
25 typedef long long ll;
26 typedef long double ld;
27 typedef unsigned long long ull;
28 typedef pair<int, int> P;
29 int n, m, k;
30 const int maxn = 1e5 + 10;
31 template <class T>
32 inline T read()
33 {
34     int f = 1;
35     T ret = 0;
36     char ch = getchar();
37     while (!isdigit(ch))
38     {
39         if (ch == '-')
40             f = -1;
41         ch = getchar();
42     }
43     while (isdigit(ch))
44     {
45         ret = (ret << 1) + (ret << 3) + ch - '0';
46         ch = getchar();
47     }
48     ret *= f;
49     return ret;
50 }
51 template <class T>
52 inline void write(T n)
53 {
54     if (n < 0)
55     {
56         putchar('-');
57         n = -n;
58     }
59     if (n >= 10)
60     {
61         write(n / 10);
62     }
63     putchar(n % 10 + '0');
64 }
65 template <class T>
66 inline void writeln(const T &n)
67 {
68     write(n);
69     puts("");
70 }
71 int main(int argc, char const *argv[])
72 {
73 #ifndef ONLINE_JUDGE
74     freopen("in.txt", "r", stdin);
75     // freopen("out.txt", "w", stdout);
76 #endif
77     ll n = read<ll>(), p = read<ll>(), w = read<ll>(), d = read<ll>();
78     int f = 0;
79     for (ll y = 0; y < w && !f; y++)
80     {
81         ll t = (p - y * d);
82         if (t % w)
83             continue;
84         if (t < 0)
85             break;
86         ll x = t / w;
87         if (x + y <= n)
88         {
89             write(x), pblank, write(y), pblank, writeln(n - x - y);
90             f = 1;
91         }
92     }
93     if (!f)
94         puts("-1");
95     return 0;
96 }
View Code

 

D. Paint the Tree

Description

给出一棵树,每个点的可以选三种颜色之一染色,给每个点染不同颜色的价格不同。

求一种染色方案满足相邻的三个节点的颜色互异且总的染色价格最小。

Solution

显然这棵树必须是一条链才可以满足染色要求。

我们可以根据点的度判断是否为一条链。

dfs求出dfs序号,由树链剖分的知识我们可以知道相邻节点的dfs序是连续的

只要确定了前三个节点的颜色那么后续都确定了,前三种一共有6种染色,跑六次取一个最小值。

  1 #include <algorithm>
  2 #include <cctype>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <map>
  9 #include <numeric>
 10 #include <queue>
 11 #include <set>
 12 #include <stack>
 13 #if __cplusplus >= 201103L
 14 #include <unordered_map>
 15 #include <unordered_set>
 16 #endif
 17 #include <vector>
 18 #define lson rt << 1, l, mid
 19 #define rson rt << 1 | 1, mid + 1, r
 20 #define LONG_LONG_MAX 9223372036854775807LL
 21 #define pblank putchar(' ')
 22 #define ll LL
 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
 24 using namespace std;
 25 typedef long long ll;
 26 typedef long double ld;
 27 typedef unsigned long long ull;
 28 typedef pair<int, int> P;
 29 int n, m, k;
 30 const int maxn = 1e5 + 10;
 31 template <class T>
 32 inline T read()
 33 {
 34     int f = 1;
 35     T ret = 0;
 36     char ch = getchar();
 37     while (!isdigit(ch))
 38     {
 39         if (ch == '-')
 40             f = -1;
 41         ch = getchar();
 42     }
 43     while (isdigit(ch))
 44     {
 45         ret = (ret << 1) + (ret << 3) + ch - '0';
 46         ch = getchar();
 47     }
 48     ret *= f;
 49     return ret;
 50 }
 51 template <class T>
 52 inline void write(T n)
 53 {
 54     if (n < 0)
 55     {
 56         putchar('-');
 57         n = -n;
 58     }
 59     if (n >= 10)
 60     {
 61         write(n / 10);
 62     }
 63     putchar(n % 10 + '0');
 64 }
 65 template <class T>
 66 inline void writeln(const T &n)
 67 {
 68     write(n);
 69     puts("");
 70 }
 71 int a[maxn][4];
 72 vector<int> g[maxn];
 73 int ind[maxn], dfn[maxn], to[maxn];
 74 int tot;
 75 void dfs(int x, int p)
 76 {
 77     dfn[x] = ++tot;
 78     to[tot] = x;
 79     int sz = g[x].size();
 80     for (int i = 0; i < sz; i++)
 81     {
 82         int y = g[x][i];
 83         if (y == p)
 84             continue;
 85         dfs(y, x);
 86     }
 87 }
 88 ll cur;
 89 ll ans[maxn], tmp[maxn];
 90 int main(int argc, char const *argv[])
 91 {
 92 #ifndef ONLINE_JUDGE
 93     freopen("in.txt", "r", stdin);
 94     // freopen("out.txt", "w", stdout);
 95 #endif
 96     n = read<int>();
 97     for (int i = 1; i <= 3; i++)
 98         for (int j = 1; j <= n; j++)
 99             a[j][i] = read<int>();
100     for (int i = 0; i < n - 1; i++)
101     {
102         int x = read<int>(), y = read<int>();
103         g[x].emplace_back(y), g[y].emplace_back(x);
104         ++ind[y], ++ind[x];
105     }
106     int f = 1, rt = -1;
107     for (int i = 1; i <= n && f; i++)
108         if (ind[i] > 2)
109             f = 0;
110         else if (ind[i] == 1)
111             rt = i;
112     if (!f)
113     {
114         puts("-1");
115         return 0;
116     }
117     dfs(rt, 0);
118     ll res = 1e16;
119     int r[] = {1, 2, 3};
120     do
121     {
122         cur = 0;
123         for (int i = 0; i < 3; i++)
124             cur += a[to[i + 1]][r[i]], tmp[i + 1] = r[i];
125         for (int i = 4; i <= n; i++)
126             cur += a[to[i]][6 - tmp[i - 1] - tmp[i - 2]], tmp[i] = 6 - tmp[i - 1] - tmp[i - 2];
127         if (cur < res)
128         {
129             for (int i = 1; i <= n; i++)
130                 ans[to[i]] = tmp[i];
131             res = cur;
132         }
133     } while (next_permutation(r, r + 3));
134     writeln(res);
135     for (int i = 1; i <= n; i++)
136         write(ans[i]), pblank;
137     return 0;
138 }
View Code

 

E. Minimizing Difference

给出一个长为n的序列和k次操作。

每次操作可以将序列里的一个值加一或者减一。

问最多k次操作后,求序列里的最小的最大最小值之差。

Solution

贪心乱搞。

记录一个当前最小值和当前最大值,以及对应出现的次数。

哪个的次数少就先搞哪个。

对于加一,二分找出原序列里大于最小值的第一个点,判断当前剩余次数能否加到下一个点,更新最小值和记录次数的哈希表。

减一同上,减一的二分查找可以先整一个原序列的相反数序列。

  1 #include <algorithm>
  2 #include <cctype>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <fstream>
  8 #include <iostream>
  9 #include <map>
 10 #include <numeric>
 11 #include <queue>
 12 #include <set>
 13 #include <stack>
 14 #if __cplusplus >= 201103L
 15 #include <unordered_map>
 16 #include <unordered_set>
 17 #endif
 18 #include <vector>
 19 #define lson rt << 1, l, mid
 20 #define rson rt << 1 | 1, mid + 1, r
 21 #define LONG_LONG_MAX 9223372036854775807LL
 22 #define pblank putchar(' ')
 23 #define ll LL
 24 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
 25 using namespace std;
 26 typedef long long ll;
 27 typedef long double ld;
 28 typedef unsigned long long ull;
 29 typedef pair<int, int> P;
 30 int n, m, k;
 31 const int maxn = 1e5 + 10;
 32 template <class T>
 33 inline T read()
 34 {
 35     int f = 1;
 36     T ret = 0;
 37     char ch = getchar();
 38     while (!isdigit(ch))
 39     {
 40         if (ch == '-')
 41             f = -1;
 42         ch = getchar();
 43     }
 44     while (isdigit(ch))
 45     {
 46         ret = (ret << 1) + (ret << 3) + ch - '0';
 47         ch = getchar();
 48     }
 49     ret *= f;
 50     return ret;
 51 }
 52 template <class T>
 53 inline void write(T n)
 54 {
 55     if (n < 0)
 56     {
 57         putchar('-');
 58         n = -n;
 59     }
 60     if (n >= 10)
 61     {
 62         write(n / 10);
 63     }
 64     putchar(n % 10 + '0');
 65 }
 66 template <class T>
 67 inline void writeln(const T &n)
 68 {
 69     write(n);
 70     puts("");
 71 }
 72 unordered_map<ll, int> mp;
 73 vector<ll> a, b;
 74 int main(int argc, char const *argv[])
 75 {
 76 #ifndef ONLINE_JUDGE
 77     freopen("in.txt", "r", stdin);
 78     // freopen("out.txt", "w", stdout);
 79 #endif
 80     n = read<int>();
 81     ll q = read<ll>();
 82     for (int i = 1; i <= n; i++)
 83     {
 84         ll x = read<ll>();
 85         ++mp[x];
 86         a.emplace_back(x);
 87         b.emplace_back(-x);
 88     }
 89     sort(a.begin(), a.end());
 90     sort(b.begin(), b.end());
 91     auto aend = unique(a.begin(), a.end());
 92     auto bend = unique(b.begin(), b.end());
 93     ll minx = a.front(), maxx = a.back();
 94     while (q)
 95     {
 96         if (minx == maxx)
 97             break;
 98         int lminx = mp[minx];
 99         int lmaxx = mp[maxx];
100         if (lminx < lmaxx)
101         {
102             auto pos = upper_bound(a.begin(), aend, minx);
103             ll dec = *pos - minx;
104             if (dec * lminx <= q)
105             {
106                 q -= dec * lminx;
107                 mp[*pos] += lminx;
108                 mp.erase(minx);
109                 minx = *pos;
110             }
111             else
112             {
113                 ll times = q / lminx;
114                 mp.erase(minx);
115                 minx += times;
116                 q = 0;
117             }
118         }
119         else
120         {
121             auto pos = upper_bound(b.begin(), bend, -maxx);
122             ll dec = maxx + *pos;
123             if (dec * lmaxx <= q)
124             {
125                 q -= dec * lmaxx;
126                 mp[-*pos] += lmaxx;
127                 mp.erase(maxx);
128                 maxx = -*pos;
129             }
130             else
131             {
132                 ll times = q / lmaxx;
133                 mp.erase(maxx);
134                 maxx -= times;
135                 q = 0;
136             }
137         }
138     }
139     writeln(maxx - minx);
140     return 0;
141 }
View Code

 

G. Running in Pairs

Description

给出两个1..n的排列,每个排列可以任意交换两个位置。

求$\sum_1^n max(a[i],b[i]) \leq k $的最大值

Solution

思路源自题解

首先对于序列里的某一个值最多只会对答案有两次贡献。

第一个和最后一个交换可以获得n-1的新贡献,

而此时再考虑第一或最后和其他值的交换不会有新贡献

那么我们就移动指针。

判断第二个和倒二,tmp=n-1-2

。。。

当此时的累计值加上当前的tmp值大于了k,就找一个最优的右值使之满足r-l+cur<=k

  1 #include <algorithm>
  2 #include <cctype>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <map>
  9 #include <numeric>
 10 #include <queue>
 11 #include <set>
 12 #include <stack>
 13 #if __cplusplus >= 201103L
 14 #include <unordered_map>
 15 #include <unordered_set>
 16 #endif
 17 #include <vector>
 18 #define lson rt << 1, l, mid
 19 #define rson rt << 1 | 1, mid + 1, r
 20 #define LONG_LONG_MAX 9223372036854775807LL
 21 #define pblank putchar(' ')
 22 #define ll LL
 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
 24 using namespace std;
 25 typedef long long ll;
 26 typedef long double ld;
 27 typedef unsigned long long ull;
 28 typedef pair<int, int> P;
 29 int n, m, k;
 30 const int maxn = 1e6 + 10;
 31 template <class T>
 32 inline T read()
 33 {
 34     int f = 1;
 35     T ret = 0;
 36     char ch = getchar();
 37     while (!isdigit(ch))
 38     {
 39         if (ch == '-')
 40             f = -1;
 41         ch = getchar();
 42     }
 43     while (isdigit(ch))
 44     {
 45         ret = (ret << 1) + (ret << 3) + ch - '0';
 46         ch = getchar();
 47     }
 48     ret *= f;
 49     return ret;
 50 }
 51 template <class T>
 52 inline void write(T n)
 53 {
 54     if (n < 0)
 55     {
 56         putchar('-');
 57         n = -n;
 58     }
 59     if (n >= 10)
 60     {
 61         write(n / 10);
 62     }
 63     putchar(n % 10 + '0');
 64 }
 65 template <class T>
 66 inline void writeln(const T &n)
 67 {
 68     write(n);
 69     puts("");
 70 }
 71 ll t[maxn];
 72 int main(int argc, char const *argv[])
 73 {
 74 #ifndef ONLINE_JUDGE
 75     freopen("in.txt", "r", stdin);
 76     // freopen("out.txt", "w", stdout);
 77 #endif
 78     n = read<int>();
 79     ll k = read<ll>();
 80     for (int i = 1; i <= n; i++)
 81         t[i] = i;
 82     ll cur = (1LL + n) * n / 2;
 83     if (k < cur)
 84     {
 85         puts("-1");
 86         return 0;
 87     }
 88     else
 89     {
 90         int l = 1, r = n;
 91         while (l < r)
 92         {
 93             int temp = r - l;
 94             if (cur + temp <= k)
 95             {
 96                 cur += temp;
 97                 swap(t[l], t[r]);
 98                 ++l, --r;
 99             }
100             else
101             {
102                 int tmp = k - cur + l;
103                 swap(t[tmp], t[l]);
104                 cur += tmp - l;
105                 break;
106             }
107         }
108     }
109     writeln(cur);
110     for (int i = 1; i <= n; i++)
111         write(i), pblank;
112     puts("");
113     for (int i = 1; i <= n; i++)
114         write(t[i]), pblank;
115 
116     return 0;
117 }
View Code

 

posted @ 2019-10-26 18:46  mool  阅读(177)  评论(0编辑  收藏  举报