CSUST 8.5 早训

Posted dwvictor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSUST 8.5 早训相关的知识,希望对你有一定的参考价值。

## Problem A

A - Meeting of Old Friends

 CodeForces - 714A

题意:

解题说明:此题其实是求两段区间的交集,注意要去除掉交集中的某个点。

题解:

C++版本一

技术图片
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
 
int main()

    long long int l1,r1,l2,r2,k,x,y;
    scanf("%lld%lld%lld%lld%lld",&l1,&r1,&l2,&r2,&k);
    x=(l1>=l2)?l1:l2;
    y=(r1<=r2)?r1:r2;
    if(r1<l2||r2<l1)
    
        printf("0\n");
    
    else
    
        if(x<=k&&k<=y)
        
            printf("%lld\n",y-x);
        
        else
        
            printf("%lld\n",y-x+1);
        
    
    return 0;
View Code

## Problem B

 B - Filya and Homework

 CodeForces - 714B 

题意:

给定一个序列,对于每一个元素,只能 + 或者 - 一个数val。这个数一旦选定,就不能改。

问能否变成全部数字都一样。

题解:

这题的正解是观察法。也可以证明。

①、全部数字都一样、有两个不同数字、三个不同数字(a[1] + a[3] =  2 * a[2])这些都易懂

那4个不同数字为什么是no呢

可以想象成找不到一个点,作为圆心,包含另外3个点(这3点在一直线)。

所以对于有三个不同数字那个,其实就是判断是否为圆心。

C++版本一

技术图片
#include <bits/stdc++.h>
using namespace std;
const int N = 5000000+10;
int a[N];
int main(int argc, char const *argv[])

int n;
cin >> n ;
for(int i = 1;i <= n ; i ++) cin >> a[i];
    sort(a + 1, a + 1 + n );
 int x  = unique(a+1,a + n+1) - a - 1;
//cout << a[1] << a[2] << a[3] << a[4] << endl;
//cout << x << endl; 
if(x < 3 || (x == 3 &&a[2] - a[1] == a[3] - a[2] ))
    cout << "YES" << endl;
    else cout << "NO" << endl;
    return 0;

View Code

## Problem C

 C - Sonya and Queries

 CodeForces - 714C

题意:

 

题解:

字典树

C++版本一

技术图片
#include <bits/stdc++.h>
using namespace std;
const int N = 5000000+10;
struct Trie

    int ch[N][3];
    int sz;
    int val[N];
    void Init()
    
        sz=1;
        memset(ch,0,sizeof ch);
        memset(val,0,sizeof val);
    

    void Insert(char *num,int op)
    
        int u=0;
        for(int i=20;i>=strlen(num);i--)
        
            if(ch[u][0]==0)
                ch[u][0]=sz++;
            u=ch[u][0];
        
        for(int i=0;i<strlen(num);i++)
        
            int c=(num[i]-0)%2;
            if(ch[u][c]==0)
                ch[u][c]=sz++;
            u=ch[u][c];
        
        val[u]+=op;
    

    int Find(char *num)
    
        int u=0;
        int cur=0;
        for(int i=20;i>=strlen(num);i--)
        
            if(ch[u][0]==0)
                return 0;
            u=ch[u][0];
            cur+=val[u];
        
        for(int i=0;i<strlen(num);i++)
        
            int c=(num[i]-0)%2;
            if(ch[u][c]==0)
                return 0;
            u=ch[u][c];
            cur+=val[u];
        
        return cur;
    
;
Trie trie;
int main()

    trie.Init();
    int q;
    scanf("%d",&q);
    getchar();
    while(q--)
    
        char s[2];
        char x[20];
        scanf("%s%s",s,x);
        //cout<<"x="<<x<<endl;
        if(s[0]==+)
            trie.Insert(x,1);
        if(s[0]==?)
            printf("%d\n",trie.Find(x));
        if(s[0]==-)
            trie.Insert(x,-1);
    
    return 0;
View Code

## Problem D

 D - Crazy Computer

 CodeForces - 716A 

题意:

题意:录入n个数,c为临界值,如果n个数中相邻的相减小于c就记录如果有一次不满足就删去前面记录的数,最后输出屏幕上存了几个数。

题解:

题意:录入n个数,c为临界值,如果n个数中相邻的相减小于c就记录如果有一次不满足就删去前面记录的数,最后输出屏幕上存了几个数。

C++版本一

技术图片
#include <bits/stdc++.h>
using namespace std;
const int N = 5000000+10;
int a[N];

int main(int argc, char const *argv[])

    int n , k;
    cin >> n >> k ;
    long long sum =  0;
    for(int i = 1;i <= n ;i ++)
        int  x;
        //cin >> x;
        cin >> a[i];
        if(a[i] - a[i - 1] > k) sum = 0;
        sum ++;

    
    cout << sum << endl;
    return 0;
View Code

## Problem E

 E - Complete the Word

 CodeForces - 716B 

题意:

题目要求的是输出全部字符串!不是满足条件的子串!!

题解:

从前往后暴力搜索满足条件的即可,依次搜26个字母。

当然如果总长度小于26肯定输出-1。

最后处理好?的填充处理就行了。

C++版本一

技术图片
#include <bits/stdc++.h>
using namespace std;
const int N = 5000000+10;
int a[N];
int vis[30];
char str[1000005];
int main(int argc, char const *argv[])

//string str;
    cin >> str;
    int n = strlen(str);
    int i = 0 ;
    if(n < 26) 
        printf("-1\n");
        return 0;
    
    bool flag = 1;
    for(int i = 0;i <= n - 26 && flag; i ++)
        int tail1 = 0 , tail2 = 0;
          memset(vis,0,sizeof vis);
        for(int j = i;j < i +  26 ;j ++)
            if(str[j] >= A && str[j] <= Z)
              //  cout << str[j] - ‘A‘ << " " << j - i << endl;
                vis[str[j] - A] ++;
            else tail2 ++;
           // if(j = i + 25) break;
        
        for(int j = 0;j < 26;j ++)
            if(vis[j] == 1)
            tail1 ++; 
        
        if(tail1 + tail2 == 26)
            int t = 0;
            for(int j = i;j < i + 26;j ++)
                if(str[j] == ?)
                    for(;t < 26;t ++)
                        if(vis[t] == 0)
                            str[j] = A + t;
                            t++;
                            break;
                        
                    
                
            
            flag = 0;
        
        
        //if(flag)
    
    for(int i = 0;i < n;i ++)
        if(str[i] == ?)
            str[i] = A;
        
    
    if(flag) cout << -1 << endl;
    else cout << str << endl;
    return 0;
View Code

## Problem F

 F - Plus and Square Root

 CodeForces - 716C 

题意:

题意:开始给你个数x=2,然后等级k为1,然后开始加等级k,如果x是完全平方数并且开方后是k+1的倍数,就对x开方,然后等级增加一级,问每升高一级需要加多少次

题解:

找规律

等级k      初始数字       加的次数*等级k       得到x         开根号后的x                       关系

                                                                                                                        √x  /  (k+1) = k    

    1               2                   +2 * 1                 4                     2                           2   /  2   =  1                  

    2               2                   +17 * 2              36                    6                           6   /  3   =  2

    3               6                   +46 * 3              144                  12                        12  /  4   =  3

    4              12                  +97 * 4              400                  20                        20  /  5   =  4

所以可以得到关系递推式:

  (k-1)*k       +       k*n         =         ( k*(k+1))²

   上一级开根         次数*等级                  新的完全平方数x

   号得到的x

所以每次所需要加的次数n =( (k*(k+1))² - (k-1)*k)/k  = k*(k+1)² - (k-1)

C++版本一

技术图片
#include <bits/stdc++.h>
using namespace std;
const int N = 5000000+10;
int a[N];
int vis[30];
char str[1000005];

int main(int argc, char const *argv[])

    long long n ;
    cin >> n ;
    if(n == 1)
        cout << "2" << endl;
    
    else
        //int ans = 2;
        cout << "2" << endl;
        //3int k = 2;
        for(long long i = 2;i <= n ;i ++)
            cout << (i * (i + 1)*(i+1) - i + 1) << endl;
           // k = sqrt(k * (i + 1) + 1);
          //  ans ++;
           
    
    return 0;
View Code

 

以上是关于CSUST 8.5 早训的主要内容,如果未能解决你的问题,请参考以下文章

CSUST 8.3 早训

CSUST 4002-你真的会字符串吗?(DP)

CSUST选拔赛题解

CSUST-4.26集训队选拔(全解)

CSUST--3.28排位周赛第六场 (全解)

2021-5-11 CSUST 周练 Codeforces Gym #102894