Codeforces Round #540 (Div. 3)题解

题目链接:

  https://codeforces.com/contest/1118

A题:

题意:

  q次查询,给你一个n,要你用1和2来凑出n,1的花费为a,2的花费为b,求花费的最小值。

思路:

  我们知道当2*a<=b时全用1来肯定是最优的,当2*a>b时,若n为奇数就是1个1其他全是2,若n为偶数就全都是2这样是最优的。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <deque>
 4 #include <queue>
 5 #include <stack>
 6 #include <cmath>
 7 #include <ctime>
 8 #include <bitset>
 9 #include <cstdio>
10 #include <string>
11 #include <vector>
12 #include <cstdlib>
13 #include <cstring>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 
18 typedef long long LL;
19 typedef pair<LL, LL> pLL;
20 typedef pair<LL, int> pLi;
21 typedef pair<int, LL> pil;;
22 typedef pair<int, int> pii;
23 typedef unsigned long long uLL;
24 
25 #define lson rt<<1
26 #define rson rt<<1|1
27 #define lowbit(x) x&(-x)
28 #define name2str(name) (#name)
29 #define bug printf("*********\n")
30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
31 #define FIN freopen("D://code//in.txt","r",stdin)
32 #define IO ios::sync_with_stdio(false),cin.tie(0)
33 
34 const double eps = 1e-8;
35 const int mod = 1000000007;
36 const int maxn = 2e5 + 7;
37 const double pi = acos(-1);
38 const int inf = 0x3f3f3f3f;
39 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
40 
41 int q;
42 LL n, a, b;
43 
44 int main(){
45     scanf("%d", &q);
46     while(q--) {
47         scanf("%lld%lld%lld", &n, &a, &b);
48         LL ans = 0;
49         if(2 * a <= b) {
50             ans = n * a;
51         } else {
52             ans = n / 2 * b + (n % 2) * a;
53         }
54         printf("%lld\n", ans);
55     }
56     return 0;
57 }
View Code

B题:

题意:

  给你n个数,要你去掉一个数,然后剩余的n-1个数保持相对顺序不变,问有多少种方案使得剩下的数中奇数项的和等于偶数项的和。

思路:

  我们知道去掉一个数后对前面的数的位置的奇偶性不会产生影响,后面的数的位置的奇偶性变为对立的,因此我们只需要求下奇数项和偶数项的前缀和即可。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <deque>
 4 #include <queue>
 5 #include <stack>
 6 #include <cmath>
 7 #include <ctime>
 8 #include <bitset>
 9 #include <cstdio>
10 #include <string>
11 #include <vector>
12 #include <cstdlib>
13 #include <cstring>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 
18 typedef long long LL;
19 typedef pair<LL, LL> pLL;
20 typedef pair<LL, int> pLi;
21 typedef pair<int, LL> pil;;
22 typedef pair<int, int> pii;
23 typedef unsigned long long uLL;
24 
25 #define lson rt<<1
26 #define rson rt<<1|1
27 #define lowbit(x) x&(-x)
28 #define name2str(name) (#name)
29 #define bug printf("*********\n")
30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
31 #define FIN freopen("D://code//in.txt","r",stdin)
32 #define IO ios::sync_with_stdio(false),cin.tie(0)
33 
34 const double eps = 1e-8;
35 const int mod = 1000000007;
36 const int maxn = 2e5 + 7;
37 const double pi = acos(-1);
38 const int inf = 0x3f3f3f3f;
39 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
40 
41 int n;
42 LL a[maxn], sum1[maxn], sum2[maxn];
43 
44 int main(){
45     scanf("%d", &n);
46     for(int i = 1; i <= n; i++) {
47         scanf("%lld", &a[i]);
48         sum1[i] = sum1[i-1];
49         sum2[i] = sum2[i-1];
50         if(i & 1) sum1[i] += a[i];
51         else sum2[i] += a[i];
52     }
53     int ans = 0;
54     for(int i = 1; i <= n; i++) {
55         if(sum1[i-1] + sum2[n] - sum2[i] == sum2[i-1] + sum1[n] - sum1[i]) {
56             ans++;
57         }
58     }
59     printf("%d\n", ans);
60     return 0;
61 }
View Code

C题:

题意:

  给你n*n个数要你构建一个每行每列都是回文的矩阵。

思路:

  模拟即可。

代码实现如下:

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;

#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)

const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 2e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;

int n, x;
int mp[25][25], cnt[1007];

int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n * n; i++) {
        scanf("%d", &x);
        cnt[x]++;
    }
    if(n % 2 == 0) {
        for(int i = 1; i <= 1000; i++) {
            if(cnt[i] % 4 != 0) {
                return printf("NO\n") * 0;
            }
        }
        int pp = 1;
        for(int i = 1; i <= n / 2; i++) {
            for(int j = 1; j <= n / 2; j++) {
                while(cnt[pp] == 0) pp++;
                mp[i][j] = mp[i][n-j+1] = mp[n-i+1][j] = mp[n-i+1][n-j+1] = pp;
                cnt[pp] -= 4;
            }
        }
    } else {
        int num1 = 0, num2 = 0, num3 = 0;
        for(int i = 1; i <= 1000; i++) {
            if(cnt[i] % 4 == 1) num1++;
            else if(cnt[i] % 4 == 2) num2++;
            else if(cnt[i] % 4 == 3) num3++;
        }
        if(num2 > 2*(n-1) || (num1 > 0 && num3 > 0) || (num1 == 0 && num3 != 1) || (num3 == 0 && num1 != 1)) return printf("NO\n") * 0;
        for(int i = 1; i <= 1000; i++) {
            if(cnt[i] % 4 == 1 || cnt[i] % 4 == 3) {
                mp[n/2+1][n/2+1] = i;
                cnt[i]--;
                break;
            }
        }
        int pp = 1;
        for(int i = 1; i <= n / 2; i++) {
            for(int j = 1; j <= n / 2; j++) {
                while(cnt[pp] < 4) pp++;
                mp[i][j] = mp[i][n-j+1] = mp[n-i+1][j] = mp[n-i+1][n-j+1] = pp;
                cnt[pp] -= 4;
            }
        }
        pp = 1;
        for(int i = 1; i <= n / 2; i++) {
            while(cnt[pp] == 0) pp++;
            mp[i][n/2+1] = mp[n-i+1][n/2+1] = pp;
            cnt[pp] -= 2;
        }
        for(int i = 1; i <= n / 2; i++) {
            while(cnt[pp] < 2) pp++;
            mp[n/2+1][i] = mp[n/2+1][n-i+1] = pp;
            cnt[pp] -= 2;
        }
    }
    printf("YES\n");
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            printf("%d ", mp[i][j]);
        }
        printf("\n");
    }
    return 0;
}
View Code

D题:

题意:

  有n杯咖啡,m页作业,每杯咖啡的权值为ai,假如你某一天喝了k杯咖啡那么你写的作业页数为a1,a2-1,a3-2……这里的1,2,3指当天喝的顺序而非原序列的下标,要你用最少的天数写完作业。

思路:

  先将ai从大到小排序,二分天数,然后把所有会产生正贡献的咖啡求和,与m比较即可。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <deque>
 4 #include <queue>
 5 #include <stack>
 6 #include <cmath>
 7 #include <ctime>
 8 #include <bitset>
 9 #include <cstdio>
10 #include <string>
11 #include <vector>
12 #include <cstdlib>
13 #include <cstring>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 
18 typedef long long LL;
19 typedef pair<LL, LL> pLL;
20 typedef pair<LL, int> pLi;
21 typedef pair<int, LL> pil;;
22 typedef pair<int, int> pii;
23 typedef unsigned long long uLL;
24 
25 #define lson rt<<1
26 #define rson rt<<1|1
27 #define lowbit(x) x&(-x)
28 #define name2str(name) (#name)
29 #define bug printf("*********\n")
30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
31 #define FIN freopen("D://code//in.txt","r",stdin)
32 #define IO ios::sync_with_stdio(false),cin.tie(0)
33 
34 const double eps = 1e-8;
35 const int mod = 1000000007;
36 const int maxn = 2e5 + 7;
37 const double pi = acos(-1);
38 const int inf = 0x3f3f3f3f;
39 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
40 
41 int n, m;
42 int a[maxn];
43 
44 bool check(int x) {
45     int tmp = 0;
46     LL sum = 0;
47     for(int i = 1; i <= min(n, x); i++) {
48         sum += a[i];
49     }
50     for(int i = x + 1; i <= n; i++) {
51         if(i % x == 1 || x == 1) tmp++;
52         if(a[i] - tmp > 0) {
53             sum += a[i] - tmp;
54         } else {
55             break;
56         }
57     }
58     return sum >= m;
59 }
60 
61 bool cmp(int a, int b) {
62     return a > b;
63 }
64 
65 int main(){
66     scanf("%d%d", &n, &m);
67     LL sum = 0;
68     for(int i = 1; i <= n; i++) {
69         scanf("%d", &a[i]);
70         sum += a[i];
71     }
72     sort(a + 1, a + n + 1, cmp);
73     if(sum < m) {
74         return printf("-1\n") * 0;
75     }
76     int ub = inf, lb = 1, mid, ans = 0;
77     while(ub >= lb) {
78         mid = (ub + lb) >> 1;
79         if(check(mid)) {
80             ub = mid - 1;
81             ans = mid;
82         } else {
83             lb = mid + 1;
84         }
85     }
86     printf("%d\n", ans);
87     return 0;
88 }
View Code

E题:

题意:

  给你n和k,要你构建n对数,假设第i对为ai,bi,第j对为aj,bj,需满足一下条件:

  1. ai!=bi;
  2. ai==aj与bi==bj不能同时成立;
  3. 若j==i+1时,ai!=aj且bi!=bj。

思路:

  第一个数一直是1~k的循环,第二个数则是2~k~1,3~k~2,4~k~2这样循环,我们知道满足题意的总排列对数只有k*(k-1)种(第一位放置方法有k种选择,第二位也有k种,故总的排列方法是k*k,其中只有1-1,2-2这种是不满足要求的),因此当n>k*(k-1)时输出NO。

代码实现如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,k;
 4 pair<int,int> ans[200007];
 5 int main(){
 6     scanf("%d%d",&n,&k);
 7     if(n>1LL*k*(k-1)) return puts("NO")*0;
 8     int a=2,x=1,y=2;
 9     for(int i = 1; i<=n;i++){
10         ans[i]={x,y};
11         x++,y++;
12         if(x>k) x = 1;
13         if(y>k) y =1;
14         if(y==a) {
15             a++;
16             if(a>k) a=1;
17             y = a;
18         }
19     }
20     puts("YES");
21     for(int i =1;i<=n;i++){
22         printf("%d %d\n",ans[i].first,ans[i].second);
23     }
24     return 0;
25 }
View Code

F1题:

题意:

  给你一棵树,每个结点的颜色可以是0,1,2,要你删除一条边使得得到的两个联通块内不能同时出现1和2。

思路:

  dfs记一下子树中的1和2的个数与总的1和2的个数比较即可。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <deque>
 4 #include <queue>
 5 #include <stack>
 6 #include <cmath>
 7 #include <ctime>
 8 #include <bitset>
 9 #include <cstdio>
10 #include <string>
11 #include <vector>
12 #include <cstdlib>
13 #include <cstring>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 
18 typedef long long LL;
19 typedef pair<LL, LL> pLL;
20 typedef pair<LL, int> pLi;
21 typedef pair<int, LL> pil;;
22 typedef pair<int, int> pii;
23 typedef unsigned long long uLL;
24 
25 #define lson rt<<1
26 #define rson rt<<1|1
27 #define lowbit(x) x&(-x)
28 #define name2str(name) (#name)
29 #define bug printf("*********\n")
30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
31 #define FIN freopen("D://code//in.txt","r",stdin)
32 #define IO ios::sync_with_stdio(false),cin.tie(0)
33 
34 const double eps = 1e-8;
35 const int mod = 1000000007;
36 const int maxn = 3e5 + 7;
37 const double pi = acos(-1);
38 const int inf = 0x3f3f3f3f;
39 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
40 
41 int n, u, v, num1, num2;
42 LL ans = 0;
43 int a[maxn], sum1[maxn], sum2[maxn];
44 vector<int> G[maxn];
45 
46 void dfs(int u, int p) {
47     if(a[u] == 1) sum1[u]++;
48     else if(a[u] == 2) sum2[u]++;
49     for(int i = 0; i < (int)G[u].size(); i++) {
50         int v = G[u][i];
51         if(v == p) continue;
52         dfs(v, u);
53         if((sum1[v] == num1 && sum2[v] == 0) || (sum2[v] == num2 && sum1[v] == 0)) ans++;
54         sum1[u] += sum1[v], sum2[u] += sum2[v];
55     }
56 }
57 
58 int main(){
59     scanf("%d", &n);
60     for(int i = 1; i <= n; i++) {
61         scanf("%d", &a[i]);
62         if(a[i] == 1) num1++;
63         else if(a[i] == 2) num2++;
64     }
65     for(int i = 1; i < n; i++) {
66         scanf("%d%d", &u, &v);
67         G[u].push_back(v);
68         G[v].push_back(u);
69     }
70     dfs(1, 0);
71     printf("%lld\n", ans);
72     return 0;
73 }
View Code

猜你喜欢

转载自www.cnblogs.com/Dillonh/p/10405917.html