Codeforces Round 894 (Div. 3)A~E题解

11 篇文章 0 订阅
10 篇文章 0 订阅

1.A. Gift Carpet

Problem - A - Codeforces

题意:

给定n行m列的矩阵,问是否可以得到从左往右的四个序列(可以不用连续),第一列中包含‘v’,第二列中包含‘i’,第三列中包含‘k’,第四列中包含‘a’。

思路:

直接枚举,用flag标记即可。(题意理解错了琢磨挺久┭┮﹏┭┮)

AC代码:

//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl	
const int M=25;
char a[M][M];
void ZB1()
{
	int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
    bool flag1=0,flag2=0,flag3=0,flag4=0;
    for(int j=1;j<=m;j++)
    {
        for(int i=1;i<=n;i++)
        {
            if(!flag1&&a[i][j]=='v')
            {
                flag1=1;
                break;
            }
            if(flag1&&!flag2&&a[i][j]=='i')
            {
                flag2=1;
                break;
            }
            if(!flag3&&flag1&&flag2&&a[i][j]=='k')
            {
                flag3=1;
                break;
            }
             if(!flag4&&flag3&&flag1&&flag2&&a[i][j]=='a')
            {
                flag4=1;
                break;
            }
        }
    }
    if(flag1&&flag2&&flag3&&flag4)Y;
    else N;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		ZB1();
	}
	return 0;
}

2.B. Sequence Game

Problem - B - Codeforces

题意:

给定一个长度为n的序列b,求满足a1=b1且对于后面的每个ai都有a[i-1]<=a[i]的序列a,规定a的长度m(n<=m<=2*m)。

思路:

枚举b,若b[i]>=b[i-1]直接放个b[i]进a,否则放两个b[i]。

AC代码:

//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl	
void ZB1()
{
	int n;
    cin>>n;
    vector<ll>b(n);
    for(int i=0;i<n;i++)cin>>b[i];
    vector<ll>a;
    a.push_back(b[0]);
    for(int i=1;i<n;i++)
    {
        if(b[i]>=b[i-1])a.push_back(b[i]);
        else
        {a.push_back(b[i]),
        a.push_back(b[i]);}
    }
    cout<<a.size()<<endl;
    for(int i=0;i<a.size();i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		ZB1();
	}
	return 0;
}

3.C. Flower City Fence

Problem - C - Codeforces

题意:

给定一个长度为n的序列a,且满足a1>=a2>=a3>=...>=an,判断将a序列各个值水平摆放后得到的序列b是否与序列a相同。
例如a=[4,2,1]--->b[3,2,1,1]

思路:

首先如果a[1]最大的数与n不相同就直接N,接着将b数组初始为0,然后每个a[i]的值对应b的下标,每个所对应的下标a的b的值++(先加上差值),之后将b从后往前,b[i]=b[i]+b[i+1]前面的加上后面的,确保堆得起来,最后再判断a与b是否相同即可。

AC代码:

//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl	
void ZB1()
{
	int n;
    cin>>n;
    vector<ll>a(n+1);
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    if(a[1]!=n)
    {
        N;
        return;
    }
    vector<ll>b(a[1]+1,0);
    for(int i=1;i<=n;i++)//b的下标a[i]那条肯定至少为高1
    {
        b[a[i]]++;
    }
    //枚举b
    for(int i=n-1;i>=1;i--)
    {
        b[i]=b[i]+b[i+1];
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i]!=b[i])
        {
            N;
            return;
        }
    }
    Y;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		ZB1();
	}
	return 0;
}

4.D. Ice Cream Balls

Problem - D - Codeforces

题意:

给一个数字n,n表示n种不同的冰激凌即n种不同的两个数字的组合(两个数字可以相同,可以不同),求最少要买多少个球即最少需要多少个数字。

思路:

由1~m个不同数字两两组合,可得组合总数为m*(m+1)/2==n,m*(m+1)==n*2

AC代码:

//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl	
void ZB1()
{
	ll n;
    cin>>n;
    if(n==1)
    {
        cout<<2<<endl;
        return;
    }
    ll d=(ll)sqrtl(2*n);
    while(d*(d+1)/2<=n)d++;
    cout<<n+d-d*(d-1)/2<<endl;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		ZB1();
	}
	return 0;
}

5.E. Kolya and Movie Theatre

Problem - E - Codeforces

题意:

给定长度为n的序列a,以及m和d,在a中可选m个数,使得娱乐值最大。娱乐值=选择的a里的m个数-d*(选择的在a中下标最大的那个数的下标),注意a中下标从1开始。

思路:

定义一个s,a从前往后枚举,只要a[i]>=0,s就加上a[i],同时加入小根堆,如果堆的数目大于m就弹出堆顶最小值s减去这个最小值,这样能保证我们的答案最大,每次操作后都取一下mx=max(mx,s-d*(i+1))

AC代码:

//gyeolhada...in bloom...dream...ricky
//string s="ricky";s.insert(0,"hello ");-->hello ricky
//transform(s.begin(), s.end(), s.begin(), ::tolower);
//2^30=1e9+73741824
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sall(x) (x).begin(),(x).end()
#define ball(x) (x).rbegin(),(x).rend()
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define Y cout<<"YES"<<endl
#define N cout<<"NO"<<endl	
void ZB1()
{
	ll n,m,d;
    cin>>n>>m>>d;
    vector<ll>a(n);
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    priority_queue<ll,vector<ll>,greater<ll>>h;
    ll mx=0,s=0;
    for(int i=0;i<n;i++)
    {
        if(a[i]>=0)
        {
            s+=a[i];
            h.push(a[i]);
        }
        if(h.size()>m)//删去最小的
        {
            s-=h.top();
            h.pop();
        }
        mx=max(mx,s-1ll*d*(i+1));//不断取最大值
    }
    cout<<mx<<endl;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		ZB1();
	}
	return 0;
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值