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

 

转载于:https://www.cnblogs.com/DWVictor/p/11305178.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值