【暑假 8.23】Loi58 && 58plus夏令营检测试

咳咳咳,作为专业划水无良没下限出题人(LOI_chairman),为了58级美好未来着想,为了祖国的繁荣昌盛,为了未来的美好世界,为了。。。。。。。

总之继承传统,为了检验58水平而出了这一份题目,总体来说比较水来着,适合新学的58嘛,前几道都是简单的水题,直接丢代码喽。

那么到了感受力量的时刻了:
出题组: chairman MeiCo Summer wyh(首字母排序)

Problem 1 Vampire与数字(num/num.cpp)

题目描述
众所周知,数字分为奇数和偶数,Vampire是一只大学霸。他的数学十分出众,一眼就能看出一个数的奇偶性。他现在要考考你对奇偶数的处理能力。
处理规则如下:
1. 先输入一个数n 再输入两个数l,r
2. 如果n为奇数 输出l到r所有数的和
3. 如果n为偶数 输出l到r中偶数的个数
4. 特别的 我们规定0为偶数

输入描述
第一行 一个整数n
第二行 两个非负整数l,r

输出描述
如果n为奇数 输出一个整数表示l到r所有数的和
如果n为偶数 输出一个整数表示l到r中偶数的个数

样例输入
1
1 2

样例输出
3

数据范围及提示
对于100%的数据:-2000 <= n <= 2000,0 <= l < r <= 2000
保证l和r属于询问区间

简单的奇偶性问题
代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
int n,l,r;
int main()
{
    freopen("num.in","r",stdin);
    freopen("num.out","w",stdout);
    scanf("%d%d%d",&n,&l,&r);
    int ans = 0; 
    if(n < 0) n = -n;
    if(n % 2 == 1)
    for(int i = l;i <= r;i ++)
    ans += i;
    if(n % 2 == 0 || n == 0)
    for(int i = l;i <= r;i ++)
    {
        if(i % 2 == 0)
        ans ++;
    }
    printf("%d",ans);
    return 0;
}

Problem 2 a筛素数(a_and_math/a_and_math.cpp)

题目描述
众所周知,a是伟大的红太阳。红太阳对数字非常敏感,他只喜欢那些可爱的数。
红太阳对“可爱的数”定义如下:在大于1的自然数中,除了1和它本身以外不再有其他因数的数。
红太阳不想亲自处理,这样会破坏数字与他的亲密度,于是他把这个问题交给了你。

输入描述
第一行两个正整数:n,m;
第二行——第m + 1行,每行两个正整数l,r,[l,r]为所询问区间(包含l和r)

输出描述
m行,对于每个询问输出一个数,为所询问区间内“可爱的数”的个数

样例输入
10 1
1 7

样例输出
4

数据范围及提示
对于100%的数据:有1 ≤ l < r ≤ n,1≤n≤1000

简单的素性判断
代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
bool flag[100010];
int n,m,l,r,s[100010];
inline void shai()
{
    flag[1]=1;
    for(int i=2;i*i<=10000;i++)
    {
        if(!flag[i])
        {
            for(int j=i*i;j<=10000;j+=i)
                flag[j]=1;
        }
    }
    for(int i=1;i<=10000;i++)
    {
        if(!flag[i])
            s[i]=s[i-1]+1; 
        else
            s[i]=s[i-1]; 
    }
}
int main()
{
    freopen("a_and_math.in","r",stdin);
    freopen("a_and_math.out","w",stdout);
    scanf("%d%d",&n,&m);
    shai();
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&l,&r);
        /*if(!flag[l])
            printf("%d\n",s[r]-s[l]+1);
        else
            printf("%d\n",s[r]-s[l]);*/
        printf("%d\n",s[r]-s[l - 1]);
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
} 

Problem 3 Summer 与排序(seq/seq.cpp)

题目描述
MMMMeico 有一个神秘的序列,有一天他被 a 要求来让这个序列焕
然一新, 但他不知究竟怎么做才能满足红太阳。 于是他请教了
SSSummer 来解决这个问题,SSSummer 听后,微微一笑,轻松解决
了这个神秘序列的问题之后又想用这个问题来考考你

输入描述
第一行有一个 n 表示序列的长度
第二行有 n 个数 表示初始的序列
第三行有一个 m 表示进行 m 此操作
接下来m行 每行对于每一个次操作给定一个ins:如果 ins = 1 后接 2 个整数 a 和 b 表示在序列的 a 位置增加 b;如果 ins = 2 输出序列中最大的那一个

输出描述
若干行 每行对应每次 ins = 2 的情况

样例输入
5
1 2 3 4 5
3
1 1 3
1 1 4
2

样例输出
8

数据范围及提示
对于 50% 的数据,1 <= n,m <= 100;
对于 70% 的数据,1 <= n,m <= 200000;
对于 90% 的数据,1 <= n,m <= 500000;
对于 100% 的数据, 1 <= n,m <= 10000000 , b >= 0;
前七个点 时限为一秒 8,9号点 时限为三秒 第10号点时限为四秒

57级去年暑假考过这个来着,emmmm,又改了改,然后强行用排序来做
这个题充分证明了卡时的优势【倒地死】,原本789跑2s多,10跑3.43s,结果经过了手读手输重载各种风之后成功缩到1s以内【颤抖】

未优化版:

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,qwq[10000010],mx=-1000000007,x,y,z;
int main()
{
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&qwq[i]),mx=max(mx,qwq[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
if(x==1)
scanf("%d%d",&y,&z),qwq[y]+=z,mx=max(mx,qwq[y]);
else
printf("%d\n",mx);
}
fclose(stdin);
fclose(stdout);
return 0;
}

优化版:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define RI register int
using namespace std;
const int MAXN = 10000000 + 5;

inline int max(int a,int b)
{
    return a > b ? a : b;
}

inline void read(int &x)
{
    x = 0;
    bool flag = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')   flag = 1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    if(flag)
        x *= -1;
}

inline void write(int x)
{
    if(x < 0)
        putchar('-'),x *= -1;
    if(x / 10)
        write(x / 10);
    putchar(x % 10 + '0');
}

int n,m,k,a,b;
int num[MAXN],maxn = -1;

int main()
{
    freopen("seq.in","r",stdin);
    freopen("seq.out","w",stdout);
    read(n);
    for(RI i = 1;i <= n;i ++)
        read(num[i]),maxn = max(maxn,num[i]);
    read(m);
    for(RI i = 1;i <= m;i ++)
    {
        read(k);
        if(k == 1)
        {
            read(a),read(b);
            num[a] += b;
            maxn = max(maxn,num[a]);
        }
        else
        {
            write(maxn);
            putchar('\n');
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

卡时出奇迹啊(:з」∠)

Problem 4 Meico 与ants(ants/ants.cpp)

题目描述
战争已经进入到紧要时间。Meico 是运输小队长,正在率领运输部
队向前线运送物资。突然,Meico 收到从指挥部发来的信息,敌军
的轰炸机正朝着你所在的独木桥飞来!为了安全,Meico 的部队必
须撤下独木桥。独木桥的长度为 L,士兵们只能呆在坐标为整数的
地方。所有士兵的速度都为 1,但一个士兵某一时刻来到了坐标为 0
或 L+1 的位置,他就离开了独木桥。
每个士兵都有一个初始面对的方向,他们会以匀速朝着这个方向行
走,中途不会自己改变方向。但是,如果两个士兵面对面相遇,他
们无法彼此通过对方,于是就分别转身,继续行走。转身不需要任
何的时间。
由于先前的愤怒,Meico 已不能控制你的士兵。甚至连每个士兵初
始面对的方向都不知道。因此,Meico 想要知道他的部队最少需要
多少时间就可能全部撤离独木桥。另外,总部安排你来阻拦敌人的
进攻,因此你还需要知道 Meico 的部队最多需要多少时间才能全部
撤离独木桥来更好地帮助他

输入描述
第一行:一个整数 L,表示独木桥的长度。桥上的坐标为 1…L
第二行:一个整数 N,表示初始时留在桥上的士兵数目
第三行:有 N 个整数,分别表示每个士兵的初始坐标。

输出描述
只有一行,输出两个整数,分别表示部队撤离独木桥的最小时间和
最大时间。两个整数由一个空格符分开。

样例输入
1 4
2
1 3

样例输出
1 2 4

数据范围及提示
初始时,没有两个士兵同在一个坐标。数据范围 N<=L<=5000

思路:
原题见luogu 1007 独木桥

做题的一个关键是把两个人相遇时折返看做两人按原来的方向与对方擦肩而过直走。然后我们就可以把士兵分开了。比方说有一个士兵在位置3,开始时向右,那么一定有一个士兵在两秒后在位置5。虽然这两个家伙可能不是同一个人,但由于士兵都是相同的,我们可以认为他们相同。

那么我们就可以把所有士兵分开。首先,我们把他们一个个读进去。然后,对于每一个士兵,他有向左和向右两种选择。设士兵在位置p,如果向左,需要p时间单位;向右,需要L-p+1个。分别取max和min,更新答案即可。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int l,n,mi=0,x,mx=0;
int main()
{
    freopen("ants.in","r",stdin);
    freopen("ants.out","w",stdout);
    scanf("%d%d",&l,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        int qaq=l+1-x;
        if(mi<min(x,qaq))
            mi=min(x,qaq);
        if(mx<max(x,qaq))
            mx=max(x,qaq);
    }
    cout<<mi<<' '<<mx;
    fclose(stdin);
    fclose(stdout);
    return 0;
} 

Problem 5 sys要算数(sys_and_rp/sys_and_rp.cpp)

题目描述
众所周知,sys非常热爱算数。现在他搞到了一些大大大大整数,想对它们搞事情。
可是那些数太大了,搞来它们已经用光了sys的rp,你能帮他搞事情吗?

输入描述
一行 给定两个大大大大整数a,b和一个运算符c,表示对a.b进行c运算

输出描述
一行,每行一个运算结果

样例输入
1 2 +

样例输出
3

数据范围及提示
对于30%的数据:1 ≤a,b ≤ 10^5
对于另外20%的数据:1 ≤a,b≤10^15 保证不含乘法
对于另外20%的数据:保证为减法运算且不出现负数
对于100%的数据:保证a,b的位数在500位之内,保证不含除法

高精度裸题hhh,但是还是感觉好手残qwq

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int a[1010],b[1010],ans[12010],lenx,leny,t,h;
int tail=1;
string x,y;
inline void jia()
{
    for(int i=1;i<=max(lenx,leny);i++)
        ans[i]=a[i]+b[i];
    for(int i=1;i<=max(lenx,leny)+1;i++)
    {
        if(ans[i]>=10)
            ans[i]%=10,ans[i+1]++;
    }
    for(int i=max(lenx,leny)+1;;i--)
    {
        if(ans[i]!=0)
        {
            tail=i;break;
        }
    } 
}
bool cha()
{
    if(lenx>leny)
        return 0;
    else if(lenx<leny)
        return 1;
    else
    {
        for(int i=lenx;i>=1;i--)
        {
            if(a[i]>b[i])
                return 0;
            else if(a[i]<b[i])
                return 1;
        }
    }
    return 1;
} 
inline void jian()
{
    if(!cha())
    {
        for(int i=1;i<=lenx;i++)
            ans[i]+=a[i]-b[i];
        for(int i=1;i<=lenx;i++)
        {
            if(ans[i]<0)
                ans[i]+=10,ans[i+1]--;
        }
        for(int i=max(lenx,leny);;i--)
        {
            if(ans[i]!=0)
            {
                tail=i;break;
            }
        } 
    }
    else
    {
        for(int i=1;i<=leny;i++)
            ans[i]+=b[i]-a[i];
        for(int i=1;i<=leny;i++)
        {
            if(ans[i]<0)
                ans[i]+=10,ans[i+1]--;
        }
        for(int i=max(lenx,leny);;i--)
        {
            if(ans[i]!=0)
            {
                tail=i;break;
            }
        } 
        cout<<'-';
    }
}
inline void cheng()
{
    for(int i=1;i<=lenx;i++)
        for(int j=1;j<=leny;j++)
            ans[i+j-1]+=a[i]*b[j];
    for(int i=1;i<=lenx+leny;i++)
    {
        if(ans[i]>=10)
            ans[i+1]+=ans[i]/10,ans[i]%=10;
    }
    for(int i=lenx+leny;;i--)
    {
        if(ans[i]!=0)
        {
            tail=i;break;
        }
    } 
}
int main()
{
    freopen("sys_and_rp.in","r",stdin);
    freopen("sys_and_rp.out","w",stdout);
    cin>>x>>y;
    lenx=x.length(),leny=y.length(),t=0,h=0;
    for(int i=1;i<=lenx;i++)
        a[i]=x[lenx-i]-'0';
    for(int i=1;i<=leny;i++)
        b[i]=y[leny-i]-'0';
    char f;
    scanf("%s",&f);
    if(f=='+')
        jia();
    else if(f=='-')
        jian();
    else if(f=='*')
        cheng(); 
    for(int i=tail;i>=1;i--)
        cout<<ans[i];
    fclose(stdin);
    fclose(stdout);
    return 0;
} 

总的来说本次考试对于监考的我们来说真是各种事故都有【望天哭】,对于58们来说更是。。。【无语凝噎】
本次考试也代表着58暑假培训最终结束,希望58级能更进一步√

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值