Codeforces Round #776 (Div. 3)

本文介绍了四道算法题目,涉及字符串处理、数值最大值计算、最优化选择序列以及序列操作。通过删除相邻字符使字符串达到目标字符、寻找特定区间内表达式的最大值、选取点对以最小化总价值以及通过操作序列使其符合特定条件。每道题目都给出了详细的解题思路和C++代码实现。
摘要由CSDN通过智能技术生成

A

Deletions of Two Adjacent Letters

题意:给你一个长度为奇数的字符串s,每次操作可以删除两个相邻的字符,可以进行无数次操作。问是否可以得到字符c

思路:因为s的长度为奇数,每次删相邻的两个字符,最后剩下的字符的位置一定是奇数。记得每次要s.clear()

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int maxx=1e6+10;
const int inf=0x3f3f3f3f;

using namespace std;
string s;
void solve()
{
    s.clear();
    cin>>s;
    char c;
    cin>>c;
    int flag=0;
    int len=s.length();
    for(int i=0;i<len;i++)
    {
        if(s[i]==c&&i%2==0)
        {
            flag=1;
            break;
        }
    }
    if(flag) printf("YES\n");
    else printf("NO\n");
}
int main()
{
    //ios;
    int _t=1;
    scanf("%d",&_t);
    while(_t--)
    {
        solve();
    }
    system("pause");
    return 0;
}

B

DIV + MOD

题意:给定x的取值区间[l,r],以及a。求表达式f(x)的最大值

思路:当x取r时,x/a最大。当x取ka-1时,x%a最大。所以在l~r区间中找最大的i使得(i+1)%a==0,答案即为max ( f(r) , f(i) )

#include <bits/stdc++.h>
typedef long long ll;
const int inf=0x3f3f3f3f;

using namespace std;
ll l,r,a;
int main()
{
    int _t=1;
    scanf("%d",&_t);
    while(_t--)
    {
        scanf("%lld %lld %lld",&l,&r,&a);
        ll ans1=r/a+r%a;
        ll ans2=-inf;
        ll ans=-inf;
        r=r-r%a;//此时r为最大的a的整数
        if(r-1>=l) ans2=(r-1)/a+(r-1)%a;
        ans=max(ans1,ans2);
        printf("%lld\n",ans);
    }
    system("pause");
    return 0;
}

C

Weight of the System of Nested Segments

题意:给定m个点的坐标和价值,从中选出n对点,使得总价值最小,且这n对点需满足i<j时,li<lj<rj<ri。输出这n对点的序号。

思路:先按价值从小到大排序,选出前2*n个点,再将这些点按坐标从小到大排序,从左右两端选点输出即可。

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int maxx=2e5+10;
const int inf=0x3f3f3f3f;

using namespace std;
struct node{
    int idx,pos,w;
}a[maxx],b[maxx];
int n,m;
bool cmp1(node a,node b)
{
    return a.w<b.w;
}
bool cmp2(node a,node b)
{
    return a.pos<b.pos;
}
void solve()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&a[i].pos,&a[i].w);
        a[i].idx=i;
    }
    int ans=0;
    sort(a+1,a+m+1,cmp1);
    for(int i=1;i<=2*n;i++)
    {
        b[i]=a[i];
        ans+=a[i].w;
    }
    sort(b+1,b+2*n+1,cmp2);
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)
    {
        printf("%d %d\n",b[i].idx,b[2*n-i+1].idx);
    }
}
int main()
{
    ios;
    int _t=1;
    scanf("%d",&_t);
    while(_t--)
    {
        getchar();
        solve();
    }
    system("pause");
    return 0;
}

D

Twist the Permutation

思路:从结果倒推,对于第i次操作,若i的位置pos!=i,ans[i]=pos,再把pos+1~i的元素放到数组的前部,1~pos放到数组后部。进行n次操作后,判断是否合法。

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int maxx=1e6+10;
const int inf=0x3f3f3f3f;

using namespace std;
int n;
int ans[maxx];
vector <int>v;
int fun(int op,vector<int>A)
{
    for(int i=0;i<A.size();i++)
    {
        if(A[i]==op)
        {
            return i; 
        }
    }
}
vector<int>sswap(int a,int b,int c,int d)
{
    vector<int>tem;
    for(int i=a;i<=b;i++)
    {
        tem.push_back(v[i]);
    }
    for(int i=c;i<=d;i++)
    {
        tem.push_back(v[i]);
    }
    return tem;
}

void solve()
{
    memset(ans,0,sizeof ans);
    v.clear();
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        v.push_back(x);
    }
    int op=n;
    while(op)
    {
        int pos=fun(op,v);
        if(pos+1!=op) ans[op]=pos+1;
        v=sswap(pos+1,op-1,0,pos);
        op--;
    }
    int flag=1;
    for(int i=1;i<v.size();i++)
    {
        if(v[i]-v[i-1]!=1)
        {
            flag=0;
            printf("-1\n");
            return ;
        }
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d%c",ans[i]," \n"[i==n]);
    }
}
int main()
{
    //ios;
    int _t=1;
    scanf("%d",&_t);
    while(_t--)
    {
        solve();
    }
    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值