• CodeForces Round #301 Div.2


    今天唯一的成果就是把上次几个人一起开房打的那场cf补一下。

    A. Combination Lock

    此等水题看一眼样例加上那个配图我就明白题意了,可是手抽没有注释掉freopen,WA了一发。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 1000 + 10;
     5 
     6 char s1[maxn], s2[maxn];
     7 
     8 int main()
     9 {
    10     int n; cin >> n;
    11     scanf("%s", s1);
    12     scanf("%s", s2);
    13     int ans = 0;
    14     for(int i = 0; i < n; i++)
    15     {
    16         int a = s1[i] - '0';
    17         int b = s2[i] - '0';
    18         if(a < b) swap(a, b);
    19         ans += min(a - b, 10 - a + b);
    20     }
    21     cout << ans << "
    ";
    22 
    23     return 0;
    24 }
    代码君

    B. School Marks

    这道题本身不难,因为所给的n是奇数。但有可能会想错细节或漏掉情况。

    n个数排好序,中间那个数一定是中位数,而且左右两边各n / 2个数。

    所以我们看已知的k个数中比y小的数有多少个,如果大于n/2个,那么中位数一定小于y,无解。

    如果k个数中不小于y的大于n / 2个,那么根据贪心,中位数已经在这些数里面了,所以剩下的n-k个数补成1就好了。

    其次可以把中位数y插到这里面去,而且能算出中位数左边要补多少个1,右边要补多少个y。

    注意在上面所有的情况中还要判断总数是否不超过x。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 1000 + 10;
     5 int a[maxn];
     6 
     7 int main()
     8 {
     9     //freopen("in.txt", "r", stdin);
    10 
    11     int n, k, p, x, y;
    12     cin >> n >> k >> p >> x >> y;
    13     for(int i = 0; i < k; i++) scanf("%d", &a[i]);
    14     sort(a, a + k);
    15     int t = lower_bound(a, a + k, y) - a;
    16     if(t > n / 2) { puts("-1"); return 0; }
    17 
    18     int s = 0;
    19     for(int i = 0; i < k; i++) s += a[i];
    20     if(k - t > n / 2)
    21     {
    22         int p = n - k;
    23         if(s + p > x) { puts("-1"); return 0; }
    24         printf("1");
    25         for(int i = 1; i < p; i++) printf(" 1");
    26         puts(""); return 0;
    27     }
    28 
    29     int l = n / 2 - t;
    30     int r = n / 2 - k + t;
    31     if(s + l + (r + 1) * y > x) { puts("-1"); return 0; }
    32     bool print = false;
    33     for(int i = 0; i < l; i++) { if(print) printf(" "); print = true; printf("1"); }
    34     for(int i = 0; i <= r; i++) { if(print) printf(" "); print = true; printf("%d", y); }
    35 
    36     return 0;
    37 }
    代码君

    C. Ice Cave (BFS)

    总体来说这场CF难度偏易,虽然比赛的时候逗比地爆一了。但是下来的时候,手写一遍,没有编译错误交上去还过了,比赛要是这状态,啧啧

    这道题一开始没有理解题意,其实就是地图上的'.'走过一遍就变成'X',而且'X'就不能再走了,终点除外。

    问从能否起点走到终点,而且把终点变成'X'

    把题意理解了,直接BFS就好啦,而且vis标记都不用,直接修改地图就好了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 500 + 10;
     5 
     6 char s[maxn][maxn];
     7 int n, m;
     8 
     9 struct Node
    10 {
    11     int x, y;
    12     Node(int x = 0, int y = 0):x(x), y(y) {}
    13 }st, ed;
    14 
    15 int dx[] = { 1, 0, -1, 0 };
    16 int dy[] = { 0, 1, 0, -1 };
    17 
    18 inline bool in(int x, int y) { return x > 0 && x <= n && y > 0 && y <= m; }
    19 
    20 bool BFS()
    21 {
    22     queue<Node> Q;
    23     Q.push(st);
    24     while(!Q.empty())
    25     {
    26         Node now = Q.front(); Q.pop();
    27         for(int i = 0; i < 4; i++)
    28         {
    29             int x = now.x + dx[i];
    30             int y = now.y + dy[i];
    31             if(!in(x, y)) continue;
    32             if(s[x][y] == 'X') { if(x == ed.x && y == ed.y) return true; continue; }
    33             s[x][y] = 'X';
    34             Q.push(Node(x, y));
    35         }
    36     }
    37     return false;
    38 }
    39 
    40 int main()
    41 {
    42     //freopen("in.txt", "r", stdin);
    43 
    44     cin >> n >> m;
    45     for(int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
    46     scanf("%d%d%d%d", &st.x, &st.y, &ed.x, &ed.y);
    47     printf("%s
    ", BFS() ? "YES" : "NO");
    48 
    49     return 0;
    50 }
    代码君

    D. Bad Luck Island (概率 DP)

    题解写得很清楚,递推或者DFS都行。

     1 #include <cstdio>
     2 #include <iostream>
     3 using namespace std;
     4 
     5 const int maxn = 100 + 5;
     6 double d[maxn][maxn][maxn];
     7 
     8 int main()
     9 {
    10     int a, b, c;
    11     cin >> a >> b >> c;
    12     d[a][b][c] = 1.0;
    13     for(int i = a; i >= 0; i--)
    14         for(int j = b; j >= 0; j--)
    15             for(int k = c; k >= 0; k--)
    16             {
    17                 if(!i && !j) continue;
    18                 if(!i && !k) continue;
    19                 if(!j && !k) continue;
    20                 double cur = d[i][j][k];
    21                 double tot = i*j + i*k + j*k;
    22                 if(i) d[i-1][j][k] += cur * (double)(i*k) / tot;
    23                 if(j) d[i][j-1][k] += cur * (double)(i*j) / tot;
    24                 if(k) d[i][j][k-1] += cur * (double)(j*k) / tot;
    25             }
    26 
    27     double aa = 0, bb = 0, cc = 0;
    28     for(int i = 1; i <= a; i++) aa += d[i][0][0];
    29     for(int i = 1; i <= b; i++) bb += d[0][i][0];
    30     for(int i = 1; i <= c; i++) cc += d[0][0][i];
    31 
    32     printf("%.12f %.12f %.12f
    ", aa, bb, cc);
    33 
    34     return 0;
    35 }
    代码君

    E. Infinite Inversions (树状数组 离散化)

    可以把所求分成两个部分来计:

    把这2n个数进行一次离散化,比如排序去重以后变成m个数。

    那么经过m次操作,这m个数相较于初始状态是一个这m个数的排列。所以可以用树状数组计算一个这m个数之间的逆序数,注意这里不涉及位置没有变化的那些数。

    这样我们便完成了第一部分的计数。

    剩下的一部分是这m个数与其他位置未发生变化的逆序数。

    预处理一下m个数中第i个数与第1个数之间有多少个数未发生位置改动sum[i]。

    比如这m个数经过n次两两交换以后,第i个数的大小为rank[i],那么未发生位置改动的数与第i个数构成的逆序对有abs(sum[i] - sum[rank[i]])

    举个栗子

    比如2 7互换,序列由

    1 2 3 4 5 6 7 8 变成 1 7 3 4 5 6 2 8

    2和7之间有4个数没有变(即3 4 5 6),对于2 7而言,7到2前面去了这是一个逆序对,也就是我们计数的第一部分。

    对于2来说,2在7的位置,而且3 4 5 6都与2构成一个逆序对,因此贡献了4个逆序对;

    对于7同样,7在2的位置,3 4 5 6在7的后面也贡献了4个逆序对。

    所以最终答案为9

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cmath>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long LL;
     8 const int maxn = 200000 + 10;
     9 
    10 int a[maxn], b[maxn], x[maxn], r[maxn];
    11 LL sum[maxn], s[maxn];
    12 int n, m;
    13 
    14 inline int lowbit(int x) { return x&(-x); }
    15 
    16 void add(int x, LL d)
    17 { while(x <= m) { s[x] += d; x += lowbit(x); } }
    18 
    19 LL query(int x)
    20 {
    21     LL ans = 0;
    22     while(x) { ans += s[x]; x -= lowbit(x); }
    23     return ans;
    24 }
    25 
    26 int main()
    27 {
    28     //freopen("in.txt", "r", stdin);
    29 
    30     cin >> n;
    31     for(int i = 1; i <= n; i++)
    32     {
    33         scanf("%d%d", &a[i], &b[i]);
    34         x[i*2-1] = a[i]; x[i*2] = b[i];
    35     }
    36     sort(x + 1, x + 1 + n*2);
    37     m = unique(x + 1, x + 1 + n*2) - x - 1;
    38     for(int i = 1; i <= m; i++)
    39     {
    40         sum[i] = sum[i - 1] + x[i] - x[i - 1] - 1;
    41         r[i] = i;
    42     }
    43     for(int i = 1; i <= n; i++)
    44     {
    45         int ta = lower_bound(x + 1, x + 1 + m, a[i]) - x;
    46         int tb = lower_bound(x + 1, x + 1 + m, b[i]) - x;
    47         swap(r[ta], r[tb]);
    48     }
    49 
    50     LL inv = 0;
    51     for(int i = m; i > 0; i--)
    52     {
    53         inv += query(r[i]);
    54         add(r[i], 1);
    55         inv += abs(sum[i] - sum[r[i]]);
    56     }
    57 
    58     cout << inv << endl;
    59 
    60     return 0;
    61 }
    代码君
  • 相关阅读:
    手机版页面跳转
    设计模式转载(史上最全设计模式导学目录|完整版)
    linux 常用命令
    数据结构与算法JavaScript描述.
    常用算法js版(冒泡排序 ,选择排序 ,插入排序 ,希尔排序 ,归并排序 ,快速排序 ,堆排序 ,计数排序 ,桶排序 ,基数排序)
    伪元素和伪类
    双向数据绑定
    2016年黑马程序员已出品各学科最新学习路线图:
    jQuery插件开发全解析
    蛋白质、碳水化合物和脂肪
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4480618.html
Copyright © 2020-2023  润新知