zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 44 (Rated for Div. 2)

    A. Chess Placing

    题解:看着像优化问题,实际上因为奇数的位置或者偶数的位置一定会被填满,所以暴力的对每个元素寻找它的适合位置。

    感受:比赛的时候想多了,如果棋子的个数较少的话感觉会有点麻烦。。。

    #pragma warning(disable:4996)
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long 
    #define lson root<<1
    #define rson root<<1|1
    #define mem(arr,in) memset(arr,in,sizeof(arr))
    using namespace std;
    
    const int maxn = 105;
    
    int n;
    int a[maxn], use[maxn];
    
    int ca_1() {
        mem(use, 0);
        for (int i = 1; i <= n; i++) if (a[i] % 2) use[a[i]] = 1;
    
        int cnt = 0;
        for (int i = 1; i <= n; i++) if (a[i] % 2 == 0) {
            for (int j = 1; j <= 2*n; j += 2) if (!use[j]) {
                cnt += abs(j - a[i]);
                use[j] = 1;
                break;
            }
        }
        return cnt;
    }
    int ca_2() { mem(use, 0); for (int i = 1; i <= n; i++) if (a[i] % 2 == 0) use[a[i]] = 1; int cnt = 0; for (int i = 1; i <= n; i++) if (a[i] % 2) { for (int j = 2; j <= 2*n; j += 2) if (!use[j]) { cnt += abs(j - a[i]); use[j] = 1; break; } } return cnt; } int main() { while (cin >> n) { n = n / 2; for (int i = 1; i <= n; i++) { cin >> a[i]; } sort(a + 1, a + n + 1); int ans = min(ca_1(), ca_2()); cout << ans << endl; } return 0; }

    B. Switches and Lamps

    题解:很直白的一道题,判断删除一个开关会影响那盏灯的状态。

    感受:这题出的很晚很无奈,,,,

    #pragma warning(disable:4996)
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long 
    #define lson root<<1
    #define rson root<<1|1
    #define mem(arr,in) memset(arr,in,sizeof(arr))
    using namespace std;
    
    const int maxn = 2005;
    
    int n, m;
    int mp[maxn][maxn], d[maxn];
    char p[maxn][maxn];
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF){
            
            for (int i = 0; i < n; i++) scanf("%s", p[i]);
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (p[i][j] == '1') mp[i][j] = 1;
                    else mp[i][j] = 0;
                }
            }
            
                mem(d, 0);
    
                for (int j = 0; j < m; j++) {
                    int cnt = 0;
                    for (int i = 0; i < n; i++) {
                        if (mp[i][j] == 1) cnt++;
                    }
                    d[j] = cnt;
                }
    
                bool flag;
                for (int i = 0; i < n; i++) {
                    flag = true;
                    for (int j = 0; j < m; j++) {
                        if (mp[i][j] == 1) {
                            if (d[j] <= 1) flag = false;
                        }
                        else {
                            if (d[j] == 0) flag = false;
                        }
                    }
                    if (flag) break;
                }
    
                if (flag) printf("YES
    ");
                else printf("NO
    ");
            
        }
        return 0;
    }

    C. Liebig's Barrels

    题解:我的想法是先排序得到最优的情况,判断是否满足,如果从位置pos就不满足的话,就从pos往前找后面剩下的桶(need)的价值,同时在从前往后找每个桶的价值。先计算前面几个桶的价值(n-need),在从后往前找剩下的几个桶的价值(need),确保一定有n个桶。具体看代码。。。

    感受:翻车最严重的一道题,,,同样的贪心思想,代码却写挂了,死活还找不到错误。。。注释掉的是我的代码,如果有朋友知道哪错了,麻烦告知一声,终于找到错误了,爽!!!!!!

    #pragma warning(disable:4996)
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long 
    #define lson root<<1
    #define rson root<<1|1
    #define mem(arr,in) memset(arr,in,sizeof(arr))
    using namespace std;
    
    const int maxn = 100005;
    
    int n, k, l, m;
    int a[maxn];
    bool use[maxn];
    
    int main()
    {
        while (scanf("%d %d %d", &n, &k, &l) != EOF) {
            m = n * k;
            for (int i = 1; i <= m; i++) scanf("%d", &a[i]);
            sort(a + 1, a + m + 1);
    
            if (a[n] - a[1] > l) printf("0
    ");
            else {
                ll ans = 0;
                int pos = m;
                for (int i = n; i <= m; i++) if (a[i] - a[1] > l) { pos = i - 1; break; }
    
                mem(use, 0);
                int cnt = 0;
                for (int i = 1; i <= pos; i += k) {
                    ans += a[i];
                    cnt++;
                    use[i] = 1;
                }
                if (cnt == n) printf("%I64d
    ", ans);
                else {
                    for (int i = pos; i >= 1; i--) if (!use[i]) {
                        ans += a[i];
                        cnt++;
                        if (cnt == n) break;
                    }
                    printf("%I64d
    ", ans);
                }
            }
            /*   
            int pos = -1;
            for (int i = 1; i <= m; i +=k) if (a[i] - a[1] > l) { pos = i; break; }
         
            ll ans = 0;
    
            if (pos == -1) {
                for (int i = 1; i <= m; i += k) ans += a[i];
                printf("%I64d
    ", ans);
            }
            else {
    
                int need = n - (pos - 1) / k;
                int cnt = 0;
                int x = -1;
           
                for (int i = pos; i >= 1; i--) if (a[i] - a[1] <= l) {
                    cnt++;
                    ans += a[i];
                    if (cnt == need) {
                        x = i;
                        break;
                    }
                }
                for (int i = 1; i < x; i += k) { ans += a[i]; cnt++; }
    
                这样的顺序不能保证凑成n个桶,实际上当a[n]-a[1]<=l,一定能凑成n个桶。!!!!!
                if (cnt != n) printf("0
    ");
                else printf("%I64d
    ", ans);
            }
            */
        }
        return 0;
    }

     D. Sand Fortress

    感受:题意不太好懂,这个题的做法很有意思,找一种构造直接满足题意的很难,但是找一种构造使某个范围内的n都满足题意的却很简单,严格的证明要去看cf提供的标解~~~~,这次受教了。

    E. Pencils and Boxes

    题解:因为这个盒子内任意两个元素之差要小于d,故先排序。假设存在答案,那么这个答案可以看作是这个序列被分作了几个区间。dp[ i ] = 1 表示第 i 个元素能够成为某个区间的第一个元素。

    dp[ i + 1 ] = 1 only if some j , i - j + 1 >= k, and dp[ j ] = 1, and a[ i ] - a[ j ] <= d。so if dp[ n + 1 ] = 1,have answer。

     1 #pragma warning(disable:4996)
     2 #include<string>
     3 #include<map>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<iostream>
     7 #include<algorithm>
     8 #define ll long long 
     9 #define lson root<<1
    10 #define rson root<<1|1
    11 #define mem(arr,in) memset(arr,in,sizeof(arr))
    12 using namespace std;
    13 typedef pair<int, int> P;
    14 
    15 const int maxn = 500005;
    16 
    17 int n, k, d;
    18 int a[maxn], dp[maxn], co[maxn];
    19 
    20 int Lowbit(int x) { return x & -x; }
    21 
    22 void add(int pos) {
    23     for (int i = pos; i <= n; i += Lowbit(i)) co[i] ++;
    24     return;
    25 }
    26 
    27 int sum(int pos) {
    28     int res = 0;
    29     for (int i = pos; i >= 1; i -= Lowbit(i)) res += co[i];
    30     return res;
    31 }
    32 
    33 int get(int l, int r) {
    34     if (l > r) return 0;
    35     return sum(r) - sum(l - 1);
    36 }
    37 
    38 int main()
    39 {
    40     while (scanf("%d %d %d", &n, &k, &d) != EOF) {
    41         mem(co, 0);
    42         mem(dp, 0);
    43         dp[1] = 1;
    44         add(1);
    45 
    46         for (int i = 1; i <= n; i++) scanf("%d", a + i);
    47         sort(a + 1, a + n + 1);
    48 
    49         int l = 1;
    50         for (int i = 1; i <= n; i++) {
    51             while (l < i && a[i] - a[l] > d) l++;
    52             dp[i + 1] = (get(l, i - k + 1) >= 1);
    53             if (dp[i + 1]) add(i + 1);
    54         }
    55 
    56         //for (int i = 1; i <= n; i++) printf("%d ", dp[i]);
    57         //cout << endl;
    58 
    59         puts(dp[n + 1] ? "YES" : "NO");
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    打印九九乘法表
    PAT (Basic Level) Practice (中文) 1091 N-自守数 (15分)
    PAT (Basic Level) Practice (中文)1090 危险品装箱 (25分) (单身狗进阶版 使用map+ vector+数组标记)
    PAT (Basic Level) Practice (中文) 1088 三人行 (20分)
    PAT (Basic Level) Practice (中文) 1087 有多少不同的值 (20分)
    PAT (Basic Level) Practice (中文)1086 就不告诉你 (15分)
    PAT (Basic Level) Practice (中文) 1085 PAT单位排行 (25分) (map搜索+set排序+并列进行排行)
    PAT (Basic Level) Practice (中文) 1083 是否存在相等的差 (20分)
    PAT (Basic Level) Practice (中文) 1082 射击比赛 (20分)
    PAT (Basic Level) Practice (中文) 1081 检查密码 (15分)
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9086099.html
Copyright © 2011-2022 走看看