zoukankan      html  css  js  c++  java
  • CodeforcesGlobalRound2(Div.2)ABCE题解

    http://codeforces.com/problemset/problem/1119/A

    题意:对于给定数列,求解 a[i] != a[j] 时 j-i+1 的最大值。

    思路:对于任意数列,假设存在某两个数字(ap,aq)不同,并且假设最长的区间就是[p,q]:a1,a2......ap,ap+1......aq......an;

       那么对于这个序列,显然ap左边的数字都必须等于aq,否则就出现了更长的区间,右边也同理。

       如此我们发现对于这个数组,a1 == ap,an == aq。显然最大的区间变成了整个数组。

       所以,无论什么数组,最长的区间一定是从左端点开始,或者到右端点结束的。所以这道题只需要暴力的找一遍就好了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int a[300005];
     5 int main(){
     6     int n;cin >> n;
     7     for(int i = 0;i < n;i ++){
     8         cin >> a[i];
     9     }
    10     int ans = 0;
    11     int L = 0;int R = n - 1;
    12     while(L <= R){
    13         if(a[L] != a[R]){
    14             ans = max(ans,R - L);
    15         }
    16         L ++;
    17     }
    18     L = 0;R = n - 1;
    19     while(L <= R){
    20         if(a[L] != a[R]){
    21             ans = max(ans,R - L);
    22         }
    23         R --;
    24     }
    25     cout << ans << endl;
    26 
    27     return 0;
    28 }
    A

    http://codeforces.com/problemset/problem/1119/B

    题意:有一个架子高度已知为 m,宽度为2,但是只能摆一排东西。现在有若干个东西,宽度都是1,但是高度不等。

       我们要依次地将这些东西摆到架子上,我们可以事先在架子上的整数高度搭上数量随意的木板,一旦搭上木板,这个架子就被彻底分成两层。再搭一块就变成三层。。。

       高度大于某一层的高度的话,这个东西就摆不到架子上。求解最多依次摆放多少个物品。

    思路:一开始被这给唬住了,一时没想到方案,后来发现是个二分。

       对于这个架子,每次二分的 mid 都代表可以从第一个摆到第 mid 个,那么对于1到 mid 的所有高度降序排序,每次处理两个物品的最大高度。

       如果这些高度的和超过了货架的总高度 m,那么就不能成功摆放。(又因为 longlong WA了一发)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n;
     5 long long m;
     6 int a[1005];
     7 
     8 int check(int x){
     9     int b[1005];
    10     for(int i = 1;i <= x;i ++){
    11         b[i] = a[i];
    12     }b[x + 1] = 0;
    13     sort(b + 1,b + 1 + x,greater<int>());
    14 //    for(int i = 1;i <= x;i ++){
    15 //        cout << b[i] << " ";
    16 //    }cout << endl;
    17     long long now = 0;
    18     for(int i = 1;i <= x;i += 2){
    19         now += max(b[i],b[i + 1]);
    20     }
    21     if(now <= m){return 1;}
    22     return 0;
    23 }
    24 
    25 int main(){
    26     cin >> n;
    27     cin >> m;
    28     for(int i = 1;i <= n;i ++){
    29         cin >> a[i];
    30     }
    31     int L = 1;int R = n;
    32     while(L < R){
    33         int mid = L + R + 1;
    34         mid /= 2;
    35         //cout << mid << " " << check(mid) << endl;
    36         if(check(mid) == 1){
    37             L = mid;
    38         }
    39         else{
    40             R = mid - 1;
    41         }
    42     }
    43     cout << L << endl;
    44 
    45     return 0;
    46 }
    B

    http://codeforces.com/problemset/problem/1119/C

    题意:给定两个大小相同的 01 矩阵,规定一种操作:选择一个第一个矩阵的子矩阵,将子矩阵的四个角取反。但是这个子矩阵至少应该是 2*2 的。

       求解第一个矩阵能否在有限步骤之内变成第二个矩阵。

    思路:口胡的答案竟然就过了。其实就是记录两个矩阵不一样的地方,因为你每次变动都是某两行改变两个数并且某两列改变两个数。

       所以如果有某行或者某列的不同点是奇数个,那么就不能转化。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int a[505][505];
     5 int b[505][505];
     6 int c[505][505];
     7 int main(){
     8     memset(c,0,sizeof(c));
     9     int n;cin >> n;
    10     int m;cin >> m;
    11     for(int i = 0;i < n;i ++){
    12         for(int j = 0;j < m;j ++){
    13             cin >> a[i][j];
    14         }
    15     }
    16     for(int i = 0;i < n;i ++){
    17         for(int j = 0;j < m;j ++){
    18             cin >> b[i][j];
    19             if(a[i][j] != b[i][j]){
    20                 c[i][j] = 1;
    21             }
    22         }
    23     }
    24     int f = 1;
    25     for(int i = 0;i < n;i ++){
    26         int cnt = 0;
    27         for(int j = 0;j < m;j ++){
    28             if(c[i][j] == 1){cnt ++;}
    29         }
    30         if(cnt % 2){f = 0;break;}
    31     }
    32     for(int i = 0;i < m;i ++){
    33         if(f == 0){break;}
    34         int cnt = 0;
    35         for(int j = 0;j < n;j ++){
    36             if(c[j][i] == 1){cnt ++;}
    37         }
    38         if(cnt % 2){f = 0;break;}
    39     }
    40     if(f){cout << "Yes" << endl;}
    41     else{cout << "No" << endl;}
    42 
    43     return 0;
    44 }
    C

    http://codeforces.com/problemset/problem/1119/D

    留坑,没想通。

    http://codeforces.com/problemset/problem/1119/E

    题意:给定一个数组。ai 代表长度为 2的 i 次方的小木棍有 ai 个。问你这些木棍能组成多少个三角形。木棍不能复用。

    思路:我们发现,对于任意三个不同长度的木棍,因为2的幂次的特性,是不会组成三角形的。所以符合题意的三角形一定是等腰或等边。

       所以在这里贪心。一开始我的思路是能等边就等边,不能等边就和前面剩下的木棍组成等腰,傻了吧唧的交上去被 WA 回来。

       后来发现贪心贪反了,应该是能等腰就等腰。

       但是对于某个ai,要注意的是,如果是偶数,就是 ai/2 个等腰,并且消耗掉前面剩余的 ai/2 个小木棍,

       如果是奇数,则会消耗掉 ai/2 - 1 个剩余小木棍,ai 中最后三个小木棍要变成等边。

       从头计算一遍即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main(){
     5     long long n;cin >> n;
     6     long long ans = 0;
     7     long long m;
     8     long long left = 0;
     9     for(int i = 0;i < n;i ++){
    10         cin >> m;
    11         if(left * 2 <= m){
    12             m -= left;
    13             m -= left;
    14             ans += left;
    15             ans += m / 3;
    16             left = m % 3;
    17         }
    18         else{
    19             ans += m / 2;
    20             left -= m / 2 - m % 2;
    21         }
    22     }
    23     cout << ans << endl;
    24 
    25     return 0;
    26 }
    E
  • 相关阅读:
    自定义Collection类
    基本排序算法(冒泡排序,选择排序,插入排序)
    泛型
    XSD的学习
    SSH整合配置
    一个可以随时插入的json的简单实现
    将Properties文件的键值对调换位置重新生成一个文件
    JAVA MD5加密
    框架中退出登录
    java 生成 xml
  • 原文地址:https://www.cnblogs.com/love-fromAtoZ/p/10673230.html
Copyright © 2011-2022 走看看