Codeforces Round #797 (Div. 3) A E F

这是自己打的第二场cf,感觉cf的前几道题就是思维题,有点找规律的意思。

A题

题意:严格满足h1>h2>h3,且答案输出的顺序是h2 h1 h3。

思路:比赛的时候用的是二分(我真是个呆呆)。和队友交流完,知道是用三的倍数来写的(这就有点总结式子,然后找规律,分类判断的意思了)。

1.理想状态下,h1=h2+1=h3+2。这样我们可以由式子h1+h2+h3=sum推出来h1=(sum+3)/3,因此如果(sum+3)能被3整除,那么就满足这个理想情况。

2.如果(sum+3)不能被3整除,也就是sum不能被3整除。那就分类讨论。

 

 

E题

题意:给了 n个货品, n 是偶数, 每个货品有价值 ai , 将货品两两配对, 两两配对和总价值为 wi, 给定 k, 求 Σ⌊wik⌋ 最大值

思路:先把每一个货品整除k的值累加到结果res里,同时对每个货物mod k,sort从小到大遍历一遍,用双指针思想,l表示左边,r表示右边。

如果num[i]+num[r]<k,那就说明这两个指针对应的货品配对在一起不能利益最大化(因为他们的余数累加起来达不到k的倍数),l++使得左指针往右走。

反之,res++(说明两个货物可以匹配),l++,r--,这样移动。

#include <bits/stdc++.h>
using namespace std;

const int N=2e5+100;
int a[N],num[N];
typedef long long ll;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        cin>>n>>k;
        ll res=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            res+=a[i]/k;
            num[i]=a[i]%k;
        }
        
        sort(num+1,num+1+n);
        int l=1,r=n;
        while(l<r)
        {
            if(num[l]+num[r]<k)l++;
            else res++,l++,r--;
        }
        
        printf("%lld\n",res);
    }
    
    
    return 0;
}

这道题也可以用stl中的multiset和low_bound() 做。刚查了查,multiset的作用是自动从小到大排序,并且不具有去重功能,可以重复存储相同的数字,时间是logn的。

 

 

F题

题意:给定一个长度为 n的字符串 s, 和一个排列 P , 每次操作让 si=sPi , 询问至少经过多少次操作能让字符串与初始状态相同

 

posted @ 2022-06-08 22:14  wellerency  阅读(47)  评论(0编辑  收藏  举报