设为首页 加入收藏

TOP

Codeforces CodeTON Round 2 (Div. 1 + Div. 2, Rated, Prizes!) A-D 题解(一)
2023-07-23 13:27:35 】 浏览:50
Tags:Codeforces CodeTON Round Div. Rated Prizes A-D 题解

A. Two 0-1 Sequences

 大致翻译:

两个长度为n和m的二进制序列a和b(题目保证n >= m)

两个操作:

op1: 改变a(2) 为min(a(1), a(2)),并且移除a(1)

op2: 改变a(2) 为max(a(1), a(2)),并且移除a(1)

每次操作后,原先的a(i)变成a(i + 1), 长度减少1,即前移。

  a二进制序列能否通过这两个操作变成b二进制序列?

解题思路:刚开始想的是判断a2后缀跟a1后缀是否相同,再判断,a1前面有没有1和0(因为有1和0,就表示op1和op2可以随意完成)。写的时候又陆陆续续发现需要几个特判,想a1长度为1等。

于是就debug,慢慢发现只要前面有a2的第一个数字,并且后缀相同就可以对了。最终写出来了。

不过我写的查找是自己造轮子,我发现大佬就是用stl中的count()来写的,就拿过来改进了改进自己的code

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <stdio.h>
#include <algorithm>
using namespace std;
 
#define rep(i,x,n) for(int i = x; i <= n; i++)
 
typedef long long LL;
typedef pair<int,int> PII;
 
const int N = 10021;
 
void solve() {
    int n, m;
    cin>>n>>m;
    string a, b;
    cin>>a>>b;
    if(a.substr(n-m+1) == b.substr(1) && count(a.begin(), a.begin() +n - m + 1, b[0])) {
        puts("YES");
    } else puts("NO");
}
void test();
int main()
{
    int n;
    cin>>n;
    while(n--) solve();
 
    return 0;
}

B. Luke is a Foodie

  大致翻译:

对于a数组中的每一个元素,满足 |v?ai|≤x, (x是固定的值,由题目给出, v是可以变化调动的值)

问最少需要调动几次v,才能使得a数组中所有元素满足|v?ai|≤x

解题思路:

用数组的话存不下1e9+21的int型,而且题目是要找改了几次v。由|v- ai| <= x这个可以发现,区间差的最大值小于二倍的x范围内,v就不会改。因此发现存max,min,每次相减,判断是否满足在范围内,满足不改,不满足将max,min赋值为k(读入值)

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <stdio.h>
#include <algorithm>
using namespace std;
 
#define rep(i,x,n) for(int i = x; i <= n; i++)
 
typedef long long LL;
typedef pair<int,int> PII;
 
//const LL N = 1e9+21;
//LL arr[N];
void test();
int main()
{
    //test();
    LL t;
    cin>>t;
    while(t--) {
        LL n,x;
        scanf("%lld %lld", &n, &x);
        LL cnt = 0;
        LL ma, mi;
        scanf("%d", &ma);
        mi = ma;
        rep(i,2,n) {
            LL k;
            scanf("%lld", &k);
            if(mi > k) mi = k;
            if(ma < k) ma = k;
            if(abs(ma - mi) <= 2*x) {;}
            else {
                cnt++;
                ma = k;
                mi = k;
            }
        }
        printf("%lld\n",cnt);
    }
 
    return 0;
}
 

C. Virus

  大致翻译:

一个圆圈内有n个房子(编号为:1、 2、 3 …… n 、 1),最初,其中的m个房子被感染了,每天被感染的房子会感染其相邻的房子(该房子未被感染或未被保护).Cirno每天可以选择一个房子保护,使他永久免疫。问Cirno在最合理的操作下,使房子感染数量最少, 输出最终房屋感染的数量。

解题思路:n跟m较大,即开n数组会溢出,那么就先从m下手。由于是形成一个 ? ,第几个第几个房子就不是那么重要,谁都可以从第一个开始。想一想,要想求最小感染房子,那反过来就是最大未感染房子(正难反易)。最大未感染房子个数,这个... 。 由于每一天房子都会有被感染的可能,怎么就最大未感染房子个数( ?? ω ?? )y,当然是从两个感染房子间隔最大的先开始咯,从两个感染房子间隔最大的先开始,堵住一个后,第二天感染,未堵住的会向内(当然还有外)感染,然后堵住那个未堵住的房子,一个间隔用两天。通过递增减去4倍的i,可以得到到它时,还有几个未被感染。

里面有一些细节,例如怎么得到第一个跟最后一个的间隔,怎么让间隔由大到小去计算。

 

 

 

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <stdio.h>
#include <algorithm>
using namespace std;

#define rep(i,x,n) for(int i = x; i <= n; i++)

typedef long long LL;
typedef pair<int,int> PII;

const int N = 100021;
int arr[N];
int diff[N];
void test();
int main()
{
    test();
    int t;
    scanf("%d", &t);
    while(t--) {
        int n,m;
        scanf("%d %d", &n, &m);
        rep(i,1,m) {
            scanf("%d", &arr[i]);
        }
        sort(arr+1, arr+m+1);
        diff[1] = arr[1] - 1 + n - arr[m];
        rep(i,2,m) diff[i] = arr[i] - arr[i-1] - 1;
        sort(diff+1, diff+m+1, greater<int>());
        int ans = 0;
        re
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++函数模板和类模板 下一篇Dijkstra算法及其C++实现-云计算..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目