9.21 Codeforces Round #587 (Div. 3)

Codeforces Round #587 (Div. 3):点击进入新世界

A. Prefixes(模拟)

原题链接:http://codeforces.com/contest/1216/problem/A

思路:

  1. 题目要求给出字符串偶数长度的前缀必须有相同数目的’a’和‘b’,要求出最小修改次数和修改后的字符串。
  2. 直接模拟。

    代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int manx=2e6+5;
char c[manx];
int a=0,b=0,ans=0;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>c[i];
        if(c[i]=='a') a++;
        else if(c[i]=='b') b++;
        if(i%2==0){
            if(a==b) continue;
            else if(a>b) c[i]='b',a=0,b=0,ans++;
            else if(a<b) c[i]='a',a=0,b=0,ans++;
        }
    }
    cout<<ans<<endl;
    for(int i=1;i<=n;i++)
    	 cout<<c[i];
    return 0;
}


B. Shooting(贪心)

原题链接:http://codeforces.com/contest/1216/problem/B

思路:

  1. 题目给定射穿罐子所需消耗的能量,每次消耗能量的总量计算公式为 s[i] = a[i] *(i-1) +1,要求最小消耗的能量,和输出射穿罐子的序号顺序。
  2. 直接把a进行由大到小排序,然后依次相加,即可。这里我是用结构体储存消耗的能量和罐子的序号。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int manx=3e5+5;

struct node{
    int nums,w;
}a[manx];

bool cmp(node a, node b)
{
    if(a.w!=b.w)
    return a.w>b.w;
    else return a.nums<b.nums;
}

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        a[i].nums=i;
        scanf("%d",&a[i].w);
    }
    sort(a+1,a+1+n,cmp);
    int ans=1;
    for(int i=2;i<=n;i++)
        ans+=a[i].w*(i-1)+1;
    cout<<ans<<endl;
    for(int i=1;i<=n;i++) cout<<a[i].nums<<" ";
    return 0;
}


C. White Sheet(思维)

原题链接:http://codeforces.com/contest/1216/problem/C

思路:

  1. 给定一张白纸的坐标和两张黑纸的坐标依次叠放,问是否能够看到白纸,能输出YES否则输出NO。(这里的看到是指能否从缝隙看到,则要考虑小数而不能单单考虑整数)
  2. 在输入一张黑纸的时候对白纸 未覆盖的部分 的坐标进行更新,然后判断是否完全覆盖即可。

AC代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
const int manx=1e6+5;
int a[manx],b[manx];
int main()
{
    int a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c4,c3,flag=1;
    cin>>a1>>a2>>a3>>a4;
    cin>>b1>>b2>>b3>>b4;
    cin>>c1>>c2>>c3>>c4;
    if(b1<=a1&&b2<=a2&&b3>=a3&&b4>=a4)
        flag=0;
    else {
        if(b1<=a1&&b2<=a2&&b3>=a3) a2=max(a2,b4);
        if(b1<=a1&&b3>=a3&&b4>=a4) a4=min(a4,b2);
        if(b1<=a1&&b2<=a2&&b4>=a4) a1=max(a1,b3);
        if(b3>=a3&&b2<=a2&&b4>=a4) a3=min(a3,b1);
    }
    if(c1<=a1&&c2<=a2&&c3>=a3&&c4>=a4)
        flag=0;
    if(flag) printf("YES");
    else printf("NO");
    return 0;
}


D. Swords(GCD)

原题链接:http://codeforces.com/contest/1216/problem/D

思路:

  1. 给定剩下剑的数量,求偷窃的人数的最小值和每个人偷窃的数量。(每个人偷窃剑的类型必须是同一类型)
  2. 要使y最小,题目所求 x应为剩下每种剑的数量的最大值。
  3. 设s 为被偷剑的总量 ,则s+= (max(a[i]) - a[i] ) 。
  4. 有 y * z =s , 要使 y 最小, 即 使 z 尽可能大, 因为每个人偷窃剑的类型必须使同一类型 , 所以即求即求每把剑被偷数量的最大公约数。
  5. 关于__gcd函数可参考:点这里 有很多STL你未见过的函数~

AC代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int manx=2e5+5;
typedef long long ll;
ll a[manx];
ll s=0,z=0,y,ans;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),ans=max(ans,a[i]);
    for(int i=1;i<=n;i++)
    {
        s+=ans-a[i];
        z=__gcd(z,ans-a[i]);
    }
    cout<<s/z<<" "<<z;
    return 0;
}



第一次打CF,掉了82分,菜…
留着坑,最近有点忙,来不及补题,等国庆补?
待续。

发布了50 篇原创文章 · 获赞 15 · 访问量 4251

猜你喜欢

转载自blog.csdn.net/JiangHxin/article/details/101123795