• Codeforces Round #297 (Div. 2)


    A题

    题目大意:

    给你一个字符串,奇数的时候是钥匙,偶数的时候是门,一把钥匙只能开对应的门,然后问你最少额外需要多少把钥匙。

    分析:

    用的数组记录一下就行,(注意的是先开门,再拿钥匙!开始错在这里了,决心好好学英语)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<string>
    using namespace std;
    int main()
    {
        int n,vist[10000];
        char a[400010];
        scanf("%d",&n);
        scanf("%s",a);
        memset(vist,0,sizeof(vist));
        vist[a[0]-'a']=1;
        int sum=0;
        int i;
        for( i=1;i<2*n-2;i=i+2)
        {
            if(vist[a[i]-'A']==0)
            {
                sum++;
            }
            else
            {
                vist[a[i]-'A']--;
            }
            vist[a[i+1]-'a']++;
        }
        printf("%d
    ",sum);
        return 0;
    }

    B题

    题目大意

    一个字符串str ,从1 开始长度为s,每次给你一个 a[i]  ,然后将  [ a[i] , (s-a[i]+1) ]  翻转,问你经过n次操作以后整个字符串是什么样的。

    分析

    需要从内到外,看那些区域需要翻转,那些区域不需要就行了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<string>
    #define  maxn 410004
    using namespace std;
    int vist[maxn],zhuan[maxn];
    
    int main()
    {
        char a[200005];
        int n,num;
        scanf("%s",a);
        int len=strlen(a);
        memset(vist,0,sizeof(vist));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num);
            vist[--num]++;
    
        }
        int sum=0;
        for(int i=0;i<len/2;i++)
        {
            sum+=vist[i];
            if(sum%2)
              swap(a[i],a[len-i-1]);
        }
        printf("%s
    ",a);
        return 0;
    }

    C题

    题目大意

    给出n条线段的长度,任意一条长度为len的线段可以当作len或len-1的线段使用,求能构成的矩形的最大的总面积(可以是多个矩形的和)。

    分析

    要是总面积最大,就要贪心,使长度最大的对子和长度次最大的对子组合,可以是多个矩形的和。
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define INF 10000000
     7 using namespace std;
     8 int main()
     9 {
    10     int n;
    11     long long a[200010];
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;i++)
    14         scanf("%I64d",&a[i]);
    15     sort(a+1,a+1+n);
    16     long long flag=0;
    17     long long ans =0;
    18     for(int i=n;i>1;)
    19     {
    20         if(a[i]==a[i-1]||a[i]-1==a[i-1])
    21         {
    22             if(flag)
    23             {
    24                 ans+=flag*a[i-1];
    25                 flag=0;
    26             }
    27             else
    28                flag=a[i-1];
    29             i=i-2;
    30         }
    31         else
    32             i--;
    33     }
    34 
    35     printf("%I64d
    ",ans);
    36     return 0;
    37 }

    D题

    题目大意

    给你一个n*m的格子,'.'代表空地,'*'代表墙,你使墙变为空地,问你最小的次数使每个空地块为矩形。

    分析

    每当搜索到有3个'.'的就让那个余下的变为空地,再次在它的四周8格以每4格搜索,直到都符合。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #include <cassert>
     6 using namespace std;
     7 
     8 char a[2005][2005];
     9 int n, m;
    10 
    11 bool check(int x, int y)
    12 {
    13     if(a[x][y] == '.' || x < 1 || y < 1 || x > n || y > m) return 0;
    14 
    15     if(a[x][y - 1] == '.' && a[x - 1][y - 1] == '.' && a[x - 1][y] == '.') return 1;
    16     if(a[x][y + 1] == '.' && a[x - 1][y + 1] == '.' && a[x - 1][y] == '.') return 1;
    17     if(a[x][y - 1] == '.' && a[x + 1][y - 1] == '.' && a[x + 1][y] == '.') return 1;
    18     if(a[x][y + 1] == '.' && a[x + 1][y + 1] == '.' && a[x + 1][y] == '.') return 1;
    19 
    20     return 0;
    21 }
    22 int x[8]= {-1,-1,0,1,1,1,0,-1};
    23 int y[8]= {0,1,1,1,0,-1,-1,-1};
    24 int main()
    25 {
    26     scanf("%d %d", &n, &m);
    27     for(int i = 1; i <= n; i++)
    28     {
    29         scanf("%s", a[i] + 1);
    30     }
    31 
    32     queue<pair<int , int> > q;
    33     for(int i = 1; i <= n; i++)
    34     {
    35         for(int j = 1; j <= m; j++)
    36         {
    37             if(check(i, j))
    38                 q.push(make_pair(i, j));
    39         }
    40     }
    41 
    42     while(!q.empty())
    43     {
    44         int i = q.front().first;
    45         int j = q.front().second;
    46         q.pop();
    47         if(!check(i, j)) continue;
    48         a[i][j] = '.';
    49         for(int ii=0; ii<8; ii++)
    50         {
    51             if( check(i + x[ii], j + y[ii]))
    52             {
    53                 q.push(make_pair(i + x[ii], j + y[ii]));
    54             }
    55         }
    56     }
    57 
    58         for(int i = 1; i <= n; i++)
    59         {
    60             printf("%s
    ", a[i] + 1);
    61         }
    62 
    63     return 0;
    64 }
  • 相关阅读:
    简单算法题20200815
    求图的连通子图的个数并保存每个子图的节点python
    java遍历树,并得到每条根到叶子节点的路径
    volatile 对于n=n+1,无效
    java重载(overload)和重写(override)
    对象的上转型对象
    (阿里巴巴笔试题)直线上安装水塔,水塔到直线上其它点的距离之和最小
    选择排序、树形排序、堆排序的java代码实现
    linux里面那些奇奇怪怪但是还没有解决的问题
    Linux使用free命令buff/cache过高
  • 原文地址:https://www.cnblogs.com/tsw123/p/4374745.html
Copyright © 2020-2023  润新知