Codeforces Round #700 (Div. 2)

A. Yet Another String Game

题目传送门:

A. Yet Another String Game

水题

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        string str;
        cin>>str;
        for(int i=0;i<str.length();i++)
        {
    
    
            if(i%2==0)
            {
    
    
                if(str[i]!='a') printf("a");
                else printf("b");
            }
            else
            {
    
    
                if(str[i]!='z') printf("z");
                else printf("y");
            }
        }
        printf("\n");
    }
    //system("pause");
    return 0;
}

B. The Great Hero

题目传送门:

B. The Great Hero

题目大意:

hero有A点攻击力和B点血量。有n只怪兽,每只怪兽有ai点攻击力和bi点血量。问hero能不能杀死所有怪兽,即使在杀完最后一只怪兽时死完。

思路:

其实这题可以写的非常的简单。
我们可以想到当能杀死怪兽时而又最惨烈的情况那就是hero用最后一滴血,杀死了攻击力最高的怪兽。也就是B - 1 + maxn >= sum (maxn为怪兽的最高攻击力,sum为杀死所有怪兽需要承受的攻击)

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL a[N],b[N];
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        LL p,q;
        int n;
        LL maxn=0;
        scanf("%lld%lld%d",&p,&q,&n);
        for(int i=1;i<=n;i++)
        {
    
    
            scanf("%lld",&a[i]);
            maxn=max(maxn,a[i]);
        }
        for(int i=1;i<=n;i++)
            scanf("%lld",&b[i]);
        q=maxn-1+q;
        LL sum=0;
        int flag=0;
        for(int i=1;i<=n;i++)
        {
    
    
            int k=b[i]/p;
            if(b[i]%p) k++;
            q=q-k*a[i];
            if(q<0) flag=1; 
        }
        if(flag==1) printf("NO\n");
        else printf("YES\n");
    }
    //system("pause");
    return 0;
}

C. Searching Local Minimum(新颖的二分查找)

题目传送门:

C. Searching Local Minimum

题目大意:

这是一个交互题,你可以查询最多100个位置的数,经过查询之后输出任意一个数 ai < min{ ai−1,ai+1} 的位置。

思路:

我们可以想到当区间中的任意位置有mid。如果a[mid] > a[mid+1],那么区间 [ mid+1 , n ]中一定存在答案,因为a[n+1]为无穷大。那么反之如果a[mid]<a[mid+1] , 那么区间[ 1 , mid ]中一定存在答案。想到这里,再结合数据范围,就很容易想到二分查找。

AC Code

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    
    int n;
    scanf("%d",&n);
    int l=1,r=n;
    int x,y;
    while(l<r)
    {
    
    
        int mid=(l+r)/2;
        printf("? %d\n",mid);
        fflush(stdout);
        scanf("%d",&x);
        printf("? %d\n",mid+1);
        fflush(stdout);
        scanf("%d",&y);
        if(x>y) l=mid+1;
        else r=mid;
    }
    printf("! %d",l);
    fflush(stdout);
    //system("pause");
    return 0;
}

D1. Painting the Array I(贪心好题)

参考了大佬的题解

题目传送门:

D1. Painting the Array I

思路:

考虑贪心
我们记当前a0数组最前面的元素为p,a1最前面的元素为q。那么a中的每一个元素,我们依次考虑分配给a0更优还是分配给a1更优。

当p==q时

显然这时候a[i]给到哪个子数组都无所谓。

当p!=a[i]&&q==a[i]

显然把a[i]丢在a0后更优

当q!=a[i]&&p==a[i]

显然把a[i]丢在a1后更优

当one!=two&&one!=a[i]&&two!=a[i]

此时放哪个位置都会让答案加一,那么怎么选择呢??

定义nxt[i]为数字i出现最近的位置

如果 nxt[p] < nxt[q] ,放在p后面更优

如果nxt[p]>nxt[q],放在q后面更优

(这里我的理解是:nxt 即为下一个相同数字的位置,那么 nxt 位置更远的中间就会存在有更多的数可以阻止两者合并,于是我们就先把当前这个数放在 nxt 更近的数后面)

AC Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
vector<int>vec[maxn];
int id[maxn],a[maxn],n;
int main()
{
    
    
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%d",&a[i]);
        vec[a[i]].push_back(i);
    }
    int p=-1,q=-1;
    int num=0;
    for(int i=1;i<=n;i++)
    {
    
    
        id[a[i]]++;
        if(p==q)    //如果相等,就随便仍一个。
        {
    
    
            if(p!=a[i])
                num++;
            p=a[i];
        }
        else if(p!=a[i]&&q==a[i])
        {
    
    
            p=a[i];
            num++;
        }
        else if(p==a[i]&&q!=a[i])
        {
    
    
            q=a[i];
            num++;
        }
        else
        {
    
    
            if(p==-1)
            {
    
    
                q=a[i];
                num++;
            }
            else if(q==-1)
            {
    
    
                p=a[i];
                num++;
            }
            else
            {
    
    
                int x=n+1,y=n+1;
                if(id[p]<vec[p].size()) x=vec[p][id[p]];
                if(id[q]<vec[q].size()) y=vec[q][id[q]];
                if(x>y) q=a[i];
                else p=a[i];
                num++;
            }
        }
    }
    printf("%d\n",num);
    //system("pause");
    return 0;
}

D2. Painting the Array II

题目传送门:

D2. Painting the Array II

方法和上面是一样的,只是各种条件反一下即可

AC Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
vector<int>vec[maxn];
int a[maxn],idx[maxn];
int main()
{
    
    
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%d",&a[i]);
        vec[a[i]].push_back(i);
    }
    int num=0;
    int p=-1,q=-1;
    for(int i=1;i<=n;i++)
    {
    
    
        idx[a[i]]++;
        if(p==q)
        {
    
    
            if(p!=a[i])
                num++;
            p=a[i];
        }
        else if(p==a[i]||q==a[i])
            continue;
        else
        {
    
    
            if(p==-1) p=a[i];
            else if(q==-1) q=a[i];
            else
            {
    
    
                int x=n+1,y=n+1;
                if(idx[p]<vec[p].size()) x=vec[p][idx[p]];
                if(idx[q]<vec[q].size()) y=vec[q][idx[q]];
                if(x<y) q=a[i];
                else p=a[i];
            }
            num++;
        }
    }
    printf("%d\n",num);
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Stevenwuxu/article/details/113757739