2024/3/12

F. Rudolf and Imbalance

原题链接:Problem - F - Codeforces

题目大意:

给n,m,k三个整数

然后输入长度分别为n,m,k的三个整数数组a,d,f。然后a数组是有序递增的,问你往a数组中插入一个d[i]+f[j]使得a数组中的相邻两项的差的最大值最小化,还可以不插入,插入一个或者不插入,使得a数组中的相邻两项的差的最大值最小化。

题目做法:

插入一次只能改变一个相邻两项差,要使得影响最大,显然想到往原本差最大的两项中间差,且插入的值越接近两项的中央越好,好平的思路的F,接下来就是代码实现了。用二分去找这个最接近中央的值。时间复杂度 m\log k,显然没问题。

AC代码:

#include<bits/stdc++.h>
#define pb(element) push_back(element)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
using namespace std;
const int maxn=1e5+100;
void solve()
{
    int n,m,k;
    set<int> ss;
    cin>>n>>m>>k;
    int a[n],d[m],f[k+1],large,seclarge;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<m;i++) cin>>d[i];
    for(int i=0;i<k;i++) cin>>f[i];
    sort(d,d+m);
    sort(f,f+k);
    f[k]=1e17;
    int ps=0;
    map<int,int> mp;
    for(int i=0;i<n-1;i++)
    {
        ss.insert(abs(a[i+1]-a[i]));
        mp[abs(a[i+1]-a[i])]++;
        if(abs(a[i+1]-a[i])>=abs(a[ps+1]-a[ps]))
        {
            ps=i;
        }
    }
    auto its=ss.end();
    its--;
    if(ss.size()==1)
    {
        seclarge=large=*its;
    }
    else
    {
        large=*its;
        its--;
        seclarge=*its;
    }
    if(mp[abs(a[ps+1]-a[ps])]!=1)
    {
        cout<<abs(a[ps+1]-a[ps])<<'\n';
    }
    else
    {
        int go=(a[ps+1]+a[ps])/2,di=d[0]+f[0];
        for(int i=0;i<m;i++)
        {
            int div1,div2;
            if(d[i]>=go) div1=d[i]+f[0],div2=d[i]+f[0];
            else
            {
                int inips=lower_bound(f,f+k+1,go-d[i])-f;
                div1=d[i]+f[inips];
                div2=d[i]+f[inips];
                if(inips!=0) div2=d[i]+f[inips-1];
            }
            if(abs(div2-go)<abs(di-go))
            {
                di=div2;
            }
            if(abs(div1-go)<abs(di-go))
            {
                di=div1;
            }
        }
        go=(a[ps+1]+a[ps])/2+1;
        int div=d[0]+f[0];
        for(int i=0;i<m;i++)
        {
            int div1,div2;
            if(d[i]>=go) div1=d[i]+f[0],div2=d[i]+f[0];
            else
            {
                int inips=lower_bound(f,f+k+1,go-d[i])-f;
                div1=d[i]+f[inips];
                div2=d[i]+f[inips];
                if(inips!=0) div2=d[i]+f[inips-1];
                //cout<<div1<<" "<<div2<<'\n';
            }
            if(abs(div2-go)<abs(div-go))
            {
                div=div2;
            }
            if(abs(div1-go)<abs(div-go))
            {
                div=div1;
            }
        }
        
        int modidif=min(max(abs(a[ps+1]-div),abs(a[ps]-div)),max(abs(a[ps+1]-di),abs(a[ps]-di)));
        //cout<<modidif<<" "<<di<<'\n';
        if(seclarge!=large) cout<<max({min(modidif,large),seclarge})<<'\n';
        else cout<<max({min(modidif,large)})<<'\n';
    }
}
signed main()
{
    fast int casen=1;
    cin>>casen;
    while(casen--) solve();
}
A. XXXXX

原题链接:https://codeforces.com/contest/1364/problem/A

题目大意:

给一个数组,问最长的subarry其和不被x整除,问这个最长的subarry的长度。

题目做法:

很平的思路,如果本身总和就满足,则输出,如果不满足,其中所有元素都被x整除则为-1。

剩余情况就是从头或者尾开始,删到第一关不被x整除的数为止,要求删得尽量少。

AC代码:

def solve():
    n, x = map(int, input().split())
    ar = list(map(int, input().split()))
    sum = 0
    flag = 0
    for i in ar:
        sum += i
        if(i % x != 0): flag = 1
    if(sum % x != 0): print(n)
    elif(sum % x == 0 and flag == 0): print("-1")
    else:
        front = 0
        back = 0
        for i in range(0, n):
            if(ar[i] % x != 0):
                front = i
                break
        for i in range(n-1, -1, -1):
            if(ar[i] % x != 0):
                back = i
                break
        # print(n, front, n - front - 1, back)
        print(max(n - front - 1, back))
casen = int(input())
for i in range(0, casen): solve()

啥时候我的python也能像c++一样熟练啊。。。。。

B. Most socially-distanced subsequence

原题链接:Problem - B - Codeforces

题目大意:

有一个全排列,要求你从其中选取一个subsequence满足如下条件

题目做法:

只有峰值需要被考虑,峰值到峰值间的数影响会被峰值覆盖。

比A还简单,就是我python真的,我真不想学python吧。。。。。

AC代码:

def solve():
    n = int(input())
    ar = list(map(int, input().split()))
    res = []
    res.append(ar[0])
    if(ar[0] > ar[0 + 1]): up = 1
    else: up = 0
    for i in range(1, n - 1):
        if(ar[i] > ar[i + 1]):
            if(up == 0): res.append(ar[i])
            up = 1
        else:
            if(up == 1): res.append(ar[i])
            up = 0
    res.append(ar[n - 1])
    print(len(res))
    for i in res:
        print(i,end = ' ')
    print('\n')
casen = int(input())
for i in range(0, casen): solve()

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值