ZZULIOJ题解

目录

1221.电梯

1222.小球滚动问题

1205.你爱我吗?

1201.众数问题

1214.盐水的故事

1215.破解简单密码

1217.统计立方数

1226.等值数目

1241.人见人爱A+B

1249.成功学生人数

1232.公交车之谜

1234.我爱淘宝

1237.童鞋你多大了?

1238.学长的鸡蛋

1239.K-String

1243.海选女主角

1296.a/b+c/d

1275.找数

1274.位数和

1279.一只小蜜蜂 

1299.连通图

1316.最高奖学金

1305.选数

1358.相邻素数距离

1473.奇怪的排序

1203.做幻方


1221.电梯

题目描述

在某一高层建筑内只有一部电梯,当你按下一个数时,电梯会运行到那一层。已知电梯每上升一层需6秒,下降一层需4秒,在需要停留的那层停留5秒。现有N个整数组成的一个需求列表,电梯将依次响应,电梯从0层开始运行,而在运行过程结束之前不会返回0层。

注意,若出现相邻两个整数相等,代表在同一层执行了两个不同任务,可以理解为:电梯已经停了5秒,正要关门时又有人在同一层按开门键,电梯又开门并停留5秒。

输入

输入分两行,第一行是一个正整数N(N<=1000),代表停留几次,第二行的N个数字代表这几次依次停留的楼层。

输出

输出电梯完成该任务序列所需的时间,单独占一行。

样例输入 Copy

3

2 3 1

样例输出 Copy

41

提示

电梯从0层上升到2层运行时间为12秒,停留5秒,再上升第三层,运行时间6秒,停留5秒,再下降到第一层,运行时间8秒,停留5秒。共41秒。

郑州轻工业大学oj上的一道基础题,使用while循环即可解决。

​#include
using namespace std;
int main()
{
    int n,m;//定义停留的次数,楼层数
    int sum=0,i=0;//初始时间和楼层数
    cin>>n;
    while(n--){
        cin>>m;

        while(im){
            sum+=4;
            i--;
        }
        
        if(i==m) sum+=5;//到了这一层,停留5秒
    }
    
    cout<

1222.小球滚动问题

题目描述

有n个小球以每秒1cm的速度在一个滑槽上滑行,滑槽没有封口,所以当小球滑到滑槽的端点时将会掉落下来。滑槽的宽度只容许一个小球通过,小球之间的碰撞为弹性碰撞(即碰撞后小球速度的绝对值不变,方向相反)。

已知n个小球的初始位置,但不知道小球的朝向,小球与槽之间的摩擦力不计,请你计算所有小球掉下所需要的最短和最长时间(秒)。

输入:
第一行输入一个整数L表示滑槽的长度(单位:cm)(1<=L<=10^6);
第二行输入一个整数n代表小球的个数(1<=n<=10^6);
第三行输入n个整数,第i个整数Xi(1<=Xi<=L)代表第i个小球的初始位置(即,距离滑槽左端Xi厘米)
输出 :
输出一行两个整数,分别代表所有小球掉落的最短和最长时间(秒)
样例输入:
10
3
2 6 7
样例输出:
4 8

我们可以知道,当没有发生碰撞时,最后一个小球下洛的时间是所有小球下落的最短时间。

我们用q[]数组存每个小球的位置,由于不知道小球从哪边下落,对于每一个小球而言,如果没有发生弹性碰撞时,离最近的槽边滑出时,时间最短。

代码段如下:

for(int i=1;i<=n;i++) 
    cin>>q[i];//存每个小球的位置sort(q+1,q+n);//对小球的位置进行排序for(int i=1;i<=n;i++) 
    b[i]=min(q[i],L-q[i]);//存离哪个槽边最近的距离int maxi=b[1];

for(int i=2;i<=n;i++)
    if(maxi

ZZULIOJ题解_第1张图片

我们如何找最长时间呢?

同意的,我们可以找没有发生碰撞的最长时间,和发生碰撞的最长时间,最后比较哪一个大。

而没有发生碰撞的,又分为所有小球都往左方向滑动 ,所有小球都往右,我们找出两者的最大值。

由于所有小球离左端的距离在上面都是排好序的,则q[n]是离左端最大的距离,在所有小球往左滑动时,时间最大,同理,L-q[1] 是所有往右小球时间最大的一个,则此阶段的代码如下:

int max1=max(q[n],L-q[1]);//max1是所有没有发生碰撞时,所耗时间最大

ZZULIOJ题解_第2张图片

而最后,就是最难理解的发生碰撞时的了,我们如何去讨论呢?

我们不妨假设第一个小球与第二个小球发生碰撞时,第三个小球往后所有的小球都向右移动,也就是说,除了第一个小球和最后一个小球,其他小球都是可以和左边或者右边的小球发生碰撞的。

我们不妨将此阶段又划分为两类:往右碰撞往左回,往左碰撞往右回 。

可能画出图比较好理解些:

ZZULIOJ题解_第3张图片

ZZULIOJ题解_第4张图片

编辑

这是往左碰撞往右弹,由于两者的速度相等,则i走的距离为l[i]=L-q[i]+q[i]-q[i-1],化简为l[i]=L-q[i-1],有点神奇哈,竟然可以消掉!

同理,往右碰撞往左回,r[i]=q[i]+q[i+1]-q[i],化简得r[i]=q[i+1]。

但是,我们刚刚护理了第一个和最后一个,我们添上:r[1]=q[2]-q[1],l[n]=L-q[n-1]。

接下来,我们上完整的代码:

#include
#include
#include
#include
#include
using namespace std;
const int N=1e6+10;
int q[N],b[N],l[N],r[N];
int main()
{
    int L,n;
    cin>>L>>n;
    for(int i=1;i<=n;i++) cin>>q[i];
    sort(q+1,q+n);
    for(int i=1;i<=n;i++){
        b[i]=min(q[i],L-q[i]);
    }
    int maxi=b[1];
    for(int i=2;i<=n;i++){
        if(maxima1) ma1=l[i];
    int ma2=r[0];
    for(int i=2;i<=n;i++)
        if(r[i]>ma2) ma2=r[i];
    cout<

ZZULIOJ题解_第5张图片

1205.你爱我吗?

题目描述

LCY买了个n束鲜花准备送给他暗恋的女生,但是他不知道这个女生是否喜欢他。这时候一个算命先生告诉他让他查花瓣数,第一个花瓣表示“爱”,第二个花瓣表示“不爱”,第三个花瓣表示“爱”......为了使最后的结果是爱,LCY需要从n束花中选出一些,你能帮他算出最后他送给女生的花中最多包含多少个花瓣吗?

输入

首先输入一个数T,表示测试的组数。

接下来T组测试实例,每组实例首先输入一行,包括一个整数n(1<=n<=100)。

然后输入一行,n个整数a1,a2,...,an(1<=ai<=100),表示每束花包含的花瓣的个数。

没有答案输出0

样例

输入
3
1
1
1
2
3
5 6 7
输出
1
0
13

我们发现只有最后是奇数时,才是“爱”, 而且如果是偶数的话,我们应该减去最小的奇数,因为偶数-奇数=奇数,如果所有花瓣中没有奇数,那么输出0.

代码如下:

#include
using namespace std;
constint N=1e6+10;
int q[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int sum=0;
        memset(q,0,sizeof(q));//初始化int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&q[i]);
            sum+=q[i];
        }
        sort(q+1,q+n);//排序int y=0;
        for(int i=1;i<=n;i++)
        {
            if(q[i]%2!=0)//找到第一小的奇数
            {
                y=q[i];break;
            }
        }
        if(y==0&&sum%2==0) printf("0\n");//如果没有奇数并且sum和为偶数,则输出0else{
            if(sum%2==0) sum-=y;
                printf("%d\n",sum);
        }
   }
        return 0;
}

ZZULIOJ题解_第6张图片

1201.众数问题

问题描述

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。

例如,S={1,2,2,2,3,5}。多重集S的众数是2,其重数是3.

对于给定的由n个自然数组成的多重集合S,计算S的众数和重数。

输入
第一行多重集S中元素的个数n(n<=50000);接下来的n行中,每行有一个自然数。
输出
输出文件有两行,第一行给出众数,第二行给出重数。(如果有多个众数,只输出较小的)。
样例输入
6
1
2
2
2
3
5
样例输出
2
3

一般的朴素做法

#include
using namespace std;
constint N=1e6+10;
int q[N],vis[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&q[i]);
        vis[q[i]]++;//记录这个数出现的次数
    }
    
    int max1=q[1];
    for(int i=2;i<=n;i++)
        if(max1vis[max2])
            max2=i;
    }
    printf("%d\n%d",max2,vis[max2]);
    return 0;
}

ZZULIOJ题解_第7张图片

暴力做法

#include
using namespace std;
constint N=1e6+10;
int max,t,ans,q[N],vis[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
        scanf("%d",&q[i]);
    for(int i=1;i<=n;i++)
    {
        ans=1;
        for(int j=i+1;j<=n;j++)
            if(q[i]==q[j]) ans++;
        vis[i]=ans;
    }
    for(int i=1;i<=n;i++)
        if(vis[i]>max)
        {
            max=vis[i];
            t=q[i];
        }
    printf("%d\n%d",t,max);
    return 0;
}

ZZULIOJ题解_第8张图片

最后一种方法,我想到的就是排序加双指针,但一直AC不了,也不知道怎么回事。

我将思想说一下,比如1 2 3 2 2 经过排序之后1 2 2 2 3,然后我们用双指针。

for(int i=1;i<=n;i++)
{
    int ans=1;
    int j=i+1;
    while(q[i]==q[j]) ans++,j++;//j一直走,直到q[i]不等于q[j]为止
    vis[i]=ans;//记录个数
    i=j-1;//更新i的值
}

ZZULIOJ题解_第9张图片

一直AC不掉,也不知道可不可行。

1214.盐水的故事

问题描述

挂盐水的时候,如果滴起来有规律,先是滴一滴,停一下;然后滴两滴,停一下;再滴三滴,停一下 ......,现在有一个问题:这瓶盐水一共有VUL毫升,每一滴是D毫升,每一滴的速度是1秒(假设最后一点不到D毫升的时间也算一秒),停一下的时间也是一秒,这瓶水什么时候能挂完?

输入
输入数据占一行,由VUL和D组成,其中0
输出
输出挂完盐水所需要的时间。
样例输入
10 1
样例输出
13
#include
using namespace std;
int main()
{
    int v,d;
    cin>>v>>d;
    int sum=0,t1=0,t2=0;
    for(int i=1;sum<=v;i++)
    {
        sum+=i*d;
        t1+=i;
        if(sum>=v) break;    //判断是否能停
        t2++;
    }
    cout<

ZZULIOJ题解_第10张图片

1215.破解简单密码

题目描述

密码是我们生活中非常重要的东西,接下来的密码:1--1,abc--2,def--3,ghi--4,jkl--5,mno--6,pqrs--7,tuv--8,wxyz--9,0--0.

小写字母变成上面那样的数字,大写字母变成小写,然后后移一位,如:X,变成小写后移一位变成了y。

样例输入
有多行实例
YUANzi1987
样例输出
zvbo941987
#include
using namespace std;
int main()
{
    char x[200];
    while(scanf("%s",&x)!=EOF)
    {
        for(int i=0;x[i]!='\0';i++)
        {
            if(x[i]>='A'&&x[i]<='Z')
                {
                    if(x[i]=='Z') x[i]='a';
                    else x[i]+=33;
                }
            else if(x[i]=='a'||x[i]=='b'||x[i]=='c') x[i]='2';
            else if(x[i]=='d'||x[i]=='e'||x[i]=='f') x[i]='3';
            else if(x[i]=='g'||x[i]=='h'||x[i]=='i') x[i]='4';
            else if(x[i]=='j'||x[i]=='k'||x[i]=='l') x[i]='5';
            else if(x[i]=='m'||x[i]=='n'||x[i]=='o') x[i]='6';
            else if(x[i]=='p'||x[i]=='q'||x[i]=='r'||x[i]=='s') x[i]='7';
            else if(x[i]=='t'||x[i]=='u'||x[i]=='v') x[i]='8';
            else if(x[i]=='w'||x[i]=='x'||x[i]=='y'||x[i]=='z') x[i]='9';
        }
        
        for(int i=0;x[i]!='\0';i++) cout<

ZZULIOJ题解_第11张图片

1217.统计立方数

题目描述

有一堆整数,每个数都小于2^32,若该数为0,则统计结束,统计有多少立方数。

样例输入
1 3 5 7 9 11 15 17 19 21 23 25 27 0
样例输出
2

暴力解决即可

#include
using namespace std;
int main()
{
    int a,b=0,i;
    while(scanf("%d",&a)!=EOF&&a)
    {
        for(int i=0;i<=sqrt(a);i++)
            if(a==i*i*i) b++;
    }
    cout<

ZZULIOJ题解_第12张图片

1226.等值数目

题目描述

已知两个整数数组f[],g[],他们的元素都从小到大排列,例如f[]中可能有1,2,2,3,3,g[]中有1,2,2,2,3.

请你写一个程序,算出这两个数组彼此之间有多少组相同的数据。就以上而言:

f[0],g[0]是一组。

f[1],g[1]是一组。

f[2],g[2]是一组。

f[3],g[4]是一组。

样例输入
5 5
1 2 2 2 3
1 2 2 3 3
样例输出
4
#include
using namespace std;
constint N=1000;
int a[N],b[N],vis[N];
int main()
{
    int x,y;
    int ans=0;
    cin>>x>>y;
    for(int i=1;i<=x;i++) cin>>a[i];
    for(int i=1;i<=y;i++) cin>>b[i];
    for(int i=1;i<=x;i++)
    {
        for(int j=1;j<=y;j++)
        {
            if(a[i]==b[j]&&vis[j]==0)
            {
                ans++;
                vis[j]++;
                break;
            }    
        }
    } 
    cout<

ZZULIOJ题解_第13张图片

1241.人见人爱A+B

题目描述

oj上面已经有十来道A+B的题目了,相信这些题目是大家的最爱,希望今天这个A+B也能给大家带来好运,这个题目不是简单的A+B,A和B都是由3个整数构成的,分别表示时分秒,假设A为34 45 56 ,就表示34小时 45分钟 56秒。

输入描述
输入有多行实例,每行有六个整数,对应的时分秒都是合法的。
输出描述
输出A+B,的值(注意:分和秒的取值0~59)
样例输入
2
1 2 3 4 5 6
34 45 56 12 23 34
样例输出
5 7 9
47 9 30

我们直接模拟一下加法和进位就可以搞定,非常简单的一道题目。

#include
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int a1,b1,c1,a2,b2,c2;
        cin>>a1>>b1>>c1>>a2>>b2>>c2;
        int a=0,b=0,c=0;
        c=c1+c2;
        while(c>=60) c-=60,b++; //进位
        b+=b1+b2;
        while(b>=60) b-=60,a++;
        a+=a1+a2;
        cout<

ZZULIOJ题解_第14张图片

1249.成功学生人数

题目描述

期末考试结束了,Ms.White拿到一个班级的成绩册,本班级共有n个学生,m门课程,每个课程的成绩是1~9中的一个整数。

如果一个学生的某一门课程得了该课程的最高分(最高分可以不唯一),则可以说该学生在该课程上是最优的,就认为该学生是成功的。请问多少学生是成功的?

输入描述
输入一行是两个整数n和m(1<=n,m<=100),n是学生个数,m是课程数目。
输出描述
输出成功的学生数目。
样例输入
4 5
9 1 7 3 8
1 2 8 4 8
1 2 1 1 1
8 1 7 1 7
样例输出
3
提示
第1,2,3号学生是成功的。
#include
using namespace std;
constint N=110;

int vis[N];

structf{
    int a[N];
};

int main()
{
    f st[N];
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>st[i].a[j];
    for(int j=1;j<=m;j++)
    {
        int max=1;
        for(int i=1;i<=n;i++)
        {
            if(st[i].a[j]>st[max].a[j]) max=i;
        }
        
        for(int i=1;i<=n;i++) //最大值可以有多个
        {
            if(st[i].a[j]==st[max].a[j]) vis[i]++;
        }
  
    }
    
    int ans=0;
    for(int i=1;i<=n;i++)
        if(vis[i]>0) ans++;
    cout<

ZZULIOJ题解_第15张图片

1232.公交车之谜

打卡!

一定要看清题目,这个题目是多组实例!

题目描述

听说紫山公园有口语角,还有很多外国人呢。为了和老外对上几句话,这周六早上birdfly拉上同伴很早就做公交车出发,这个公园一共有n(1<=n<=20)站路,birdfly刚上车时有m个人,每一站都有pi个人上车,qi个人下车,请问这一路最多有多少人?(0<=m,pi,qi<=50).

输入
输入有多组样例,每组样例第一行两个数n,m,接下来n行每行两个数pi,qi。
输出
每组实例占一行。
样例输入
2 3
5 2
3 5
样例输出
6
#include
#include
using namespace std;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        vector C;
        for(int i=1;i<=n;i++)
        {
            int a,b;
            cin>>a>>b;
            m+=a-b;
            C.push_back(m);
        }
        int max=0;
        for(int i=1;iC[max]) max=i;
        cout<

ZZULIOJ题解_第16张图片

1234.我爱淘宝

打卡!

题目描述

最近superbin爱上了淘宝,一口气花重金买了很多宝贝,不过有很多排序方式:

1.按价格从低到高排序;

2. 按价格从高到低排序;

3.按销售量从高到低排序;

输入描述
有多组测试数据,每组测试数据第一行是两个整数n,m,n表示有n件物品,1<=n<=100,m表示排序的方式(1<=m<=3),接下来的n行每一行是一个物品的信息,包括:a.物品的名字,由字母数字组成,长度不超过100,且不为空;b.价格price,为正整数;c.销售量;
如果排序的关键词相同,就按名字的字典序排列,保证没有重复名字。
输出描述
输出排序后的结果
样例输入
3 1
Tshirt1 39 100
Tshirt2 49 10
Tshirt3 129 3
样例输出
Tshirt1 39 100
Tshirt2 49 10
Tshirt3 129 3
#include
using namespace std;
structf
{
    string name;
    int a;
    int b;
};

bool cmp1(const f &A,const f &B)
{
    if(A.a==B.a) return A.nameB.a;
}

bool cmp3(const f &A,const f &B){
    if(A.b==B.b) return A.nameB.b;
}
int main()
{
    int n,op;
    while(cin>>n>>op)
    {
        f st[110];
        for(int i=0;i>st[i].name>>st[i].a>>st[i].b;
        if(op==1) sort(st,st+n,cmp1);
        elseif(op==2) sort(st,st+n,cmp2);
        elsesort(st,st+n,cmp3);
        for(int i=0;i

ZZULIOJ题解_第17张图片

1237.童鞋你多大了?

题目描述

有5人坐在一起,当问第5个人多少岁,他说比第4个人大2岁,问第4个人多少岁,他说比第3个人大2岁,依此下去,问第一个人多少岁,他说他10岁,最后求第5个人多少岁?如果所坐的不是5人而是n人,写出第n个人的年龄。

输入

N组实例,每组实例输入两个整数,n,m。第一个表示n个人,第二个表示最后一个被问的人的年龄。

输出

输出第n个人的年龄,占一行

样例输入 Copy

1

2 1

样例输出 Copy

3

#include
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        cout<

1238.学长的鸡蛋

题目描述

今天吃午饭的时候,ZY的鸡蛋不小心从碗里掉了出来,-_-#

假设这个鸡蛋从m米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在

第n次落地时,共经过多少米?(假设鸡蛋不会破。。PS:轻院的鸡蛋质量就是好!)

输入

输入数据有多组,每组占一行,分别为一个m,和n,m和n的定义如上。

输出

输出第n次落地时,共经过多少米?n<20,m<100,结果保留两位小数

样例输入 Copy

100 1

100 2

样例输出 Copy

100.00

200.00

#include
using namespace std;
int main()
{
    double x;
    int n;
    while(cin>>x>>n)
    {
        double sum=0;
        double l=x;
        x*=2;
        while(n--)
        {
            sum+=x;
            x/=2;
        }
        printf("%0.2lf\n",sum-l);
    }
    return 0;
}

1239.K-String

题目描述

如果一个字符串能够由k个相同的字符串组成,那么这个字符串就叫做K-String.例如:字符串aabaabaabaab既是1-string,又是2-string,4-string,很明显,对于任何一个字符串都是1-string。

现在给你一个字符串S(仅包含大小写字母)和一个整数k,你的任务是将S排序,使其成为一个k-string。

输入描述
多组测试
每组实例占两行,第一行是k(1<=k<=10000.第二行是S
输出描述
如果是k-string,输出Yes,否则输出No

非常简单的一道题目,用map容器即可。

#include
#include
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        map mp;
        int k;
        cin>>k;
        string x;
        cin>>x;
        for(int i=0;i::iterator it=mp.begin();it!=mp.end();it++)
        {
            if(it->second%k==0) ans++;
            sum++;
        }
        if(ans==sum) cout<<"Yes"<

ZZULIOJ题解_第18张图片

1243.海选女主角

题目描述

potato老师虽然很喜欢教书,但是迫于生活压力,不得不想办法在业余时间挣点外快以养家糊口。

“做什么比较挣钱呢?筛沙子没力气,看大门又不够帅...”potato老师很是无奈。

“张艺谋比你还难看,现在多有钱呀,听说还要导演奥运开幕式呢!你为什么不去娱乐圈发展呢?”lwg在一旁出主意。

嗯,也是,为了生存,就委屈点到娱乐圈混混吧,马上就拍一部激光电影《杭电记忆——回来我的爱》。

说干就干,马上海选女主角(和老谋子学的,此举可以吸引媒体的眼球,呵呵),并且特别规定,演员必须具有ac的基本功,否则直接out!

由于策划师风之鱼(大师级水王)宣传到位,来应聘的MM很多,当然包括nit的蛋糕妹妹等呼声很高的美女,就连zjut的jqw都男扮女装来应聘(还好被安全顾问hdu_Bin-Laden认出,给轰走了),看来娱乐圈比acm还吸引人哪...

面试那天,刚好来了m*n个MM,站成一个m*n的队列,副导演Fe(OH)2为每个MM打了分数,分数都是32位有符号整数。

一开始我很纳闷:分数怎么还有负的?Fe(OH)2解释说,根据选拔规则,头发染成黄色、化妆太浓、穿的太少等等都要扣分数的,扣的多了就可能是负分了,当然,如果发现话语中夹有日语,就直接给-2147483648分了。

分数送上来了,是我做决定的时候了,我的一个选拔原则是,要选一个面试分数绝对值(必须还是32位整数)最大的MM。

特别说明:如果不幸选中一个负分的MM,也没关系,因为我觉得,如果不能吸引你,那要想法恶心你。

输入

输入数据有多组,每组的第一行是两个整数m和n,表示应聘MM的总共的行列数,然后是m行整数,每行有n个,m和n的定义见题目的描述。

输出

对于每组输入数据,输出三个整数x,y和s,分别表示选中的MM的行号、列号和分数。

note:行号和列号从一开始,如果有多个MM的分数绝对值一样,那么输出排在最前面的一个(即行号最小的那个,如果行号相同则取列号最小的那个)。

样例输入 Copy

2 3

1 4 -3

-7 3 0

样例输出 Copy

2 1 -7

#include
using namespace std;
const int N=1000;
int a[N][N];
int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>a[i][j];
        int l=0,r=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(abs(a[i][j])>abs(a[l][r])
                {
                    l=i;
                    r=j;
                }
            }
        }
        cout<

1296.a/b+c/d

题目描述

给你两个分数,求他们的和,并要求和为最简的形式。

输入描述
输入一个T(T<=1000),表示有T组数据,然后是T行数据,每行四个正整数a,b,c,d化成最简的形式为e/f
输出描述
输出e f
样例输入
2
1 2 1 3
4 3 2 3
样例输出
5 6
2 1
#include
using namespace std;

int gcd(int a,int b)
{
    return b ? gcd(b,a%b) : a;
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        int f=b*d/gcd(b,d);
        int e=a*(f/b)+c*(f/d);
        int q=gcd(e,f);
        cout<

ZZULIOJ题解_第19张图片

1275.找数

题目描述

首先给你一个n个有序序列,如何给你m个数,你能快速确定这m个数在这n个数中出现过吗?

数据范围
0<=n<=1000000
0<=m<=1000000
0<=序列的值<=1e9
样例输入
10
1 2 4 5 7 8 9 10 12 15
5
4 6 13 10 12
样例输出
3
no
no
8
9

刚开始想到的是哈希表,但是发现不符合哈希表模板,就想到了二分。

#include
using namespace std;
const int N=1000100;
int q[N];
int search(int l,int r,int x)
{
    while(l>1;
        if(q[mid]>n;
    for(int i=1;i<=n;i++) cin>>q[i];
    cin>>m;
    while(m--)
    {
        int x;
        cin>>x;
        if(q[search(1,n,x)]==x) cout<

1274.位数和

题目描述

位数和即Digit-sum。一个整数的Digit-sum就是:十进制表示下的整数的各个位数的和,例如1234的Digit-sum就是1+2+3+4=10,3443的Digit-sum就是3+4+4+3=14.

现在问题是:给你三个正整数A,B和C,在A和B之间找一个整数X,使得X的Digit-sum与C的Digit-sum的最接近,如果存在多个X则输出最小的那个。

输入描述
输入有多组测试,第一行一个整数n,表示有n行测试数据;
每组测试包含三个整数A,B,C(1<=A,B,C<=1000000000)
输出描述
每组输出一个X
样例输入
3
1 9 10
10 20 20
1 1 999
样例输出
1
11
1

非常简单的一道比较题,用vector即可解决。

#include
#include
using namespace std;
int f(int n)
{
    int ans=0;
    while(n>0)
    {
        ans+=n%10;
        n/=10;
    }
    return ans;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        vector mp;
        int a,b,c;
        cin>>a>>b>>c;
        for(int i=a;i<=b;i++)
            mp.push_back(abs(f(i)-f(c)));
        int min=0;
        for(int i=1;i

ZZULIOJ题解_第20张图片

1279.一只小蜜蜂 

 打卡! 

题目描述

有一只小蜜蜂只能往右走,不能往回走,图如下:

 

请问从m走到n有多少种走法;

有多组测试。

样例输入

2

1 2

3 6 

样例输出

1

斐波拉数列的应用,1可以走到2和3,如果从1开始,走到n,则fn=fn-1+fn-2;

#include
using namespace std;
typedef long long ll;
int main()
{
    ll a,b,f1,f2,f;
    int t;
    cin>>t;
    while(t--)
    {
        cin>>a>>b;
        f=0,f1=1;
        for(int i=a;I<=b;i++)
        {
            f2=f+f1;
            f=f1;
            f1=f2;
        }
        cout<

1299.连通图

 题目描述

给你一个无向图,还有这个图上顶点与顶点之间的边,你能判断这个连通图吗?也就是能否从任意一个点开始可以直接或者间接访问到图上的任何一个顶点。

输入描述

首先输入一个整数t,表示有t组例子。

每组例子包括两部分;

第一部分(占一行):一个整数n和m表示图的个数和边的个数。

第二部分(有m行):每行两个整数s和t,表示s和t之间有一条边(顶点为1~n,其中1<=s,t<=n,1<=n<=100)。 

输出描述

对于每组例子,如果此图为连通图,输出yes,否则输出no。 

样例输入

2

4 4

1 2

1 3

1 4

2 4

4 3

1 2

2 4

1 4 

样例输出

yes

no 

并查集的应用,维护每个节点的边的个数。

#include
using namespace std;
const int N=1e6+10;
int p[N],size[N];

int find(int x)
{
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(p,0,sizeof(p));
        memset(size,0,sizeof(size));
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++) p[i]=i,size[i]=1;
        while(m--)
        {
            int a,b;    
            cin>>a>>b;
            if(find(a)==find(b)) continue;
            size[find(b)]+=size[find(a)];
            p[find(a)]=find(b);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
            if(size[find(i)]==n) ans++; //每个点可以到所有的边
        if(ans==n) cout<<"yes"<

1316.最高奖学金

题目描述

    某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:

    1)  院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上
        论文的学生均可获得;

    2)  五四奖学金,每人4000元,期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)
        的学生均可获得;

    3)  成绩优秀奖,每人2000元,期末平均成绩高于90分(>90)的学生均可获得;

    4)  西部奖学金,每人1000元,期末平均成绩高于85分(>85)的西部省份学生均可获得;

    5)  班级贡献奖,每人850元,班级评议成绩高于80分(>80)的学生干部均可获得;

    只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。
    例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,
    那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。

    现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高
    (假设总有同学能满足获得奖学金的条件)。

输入

    输入的第一行是一个整数N(1 <= N <= 100),表示学生的总数。
    接下来的N行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,
    班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。
    姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);
    期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);
    是否是学生干部和是否是西部省份学生分别用一个字符表示,Y表示是,N表示不是;
    发表的论文数是0到10的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。

输出

输出包括三行,
第一行是获得最多奖金的学生的姓名,
第二行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。
第三行是这N个学生获得的奖学金的总数。

样例输入 Copy

4
YaoLin 87 82 Y N 0
ChenRuiyi 88 78 N Y 1
LiXin 92 88 N N 0
ZhangQin 83 87 Y N 1

样例输出 Copy

ChenRuiyi
9000
28700
#include
using namespace std;
const int N=1e6+10;
struct f{
    string name;
    int a;
    int b;
    char x;
    char y;
    int c;
    int d=0;
};

int main()
{
    f st[10000];
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>st[i].name>>st[i].a>>st[i].b>>st[i].x>>st[i].y>>st[i].c;
    for(int i=1;i<=n;i++)
    {
        if(st[i].a>80&&st[i].c>=1) st[i].d+=8000;
        if(st[i].a>85&&st[i].b>80) st[i].d+=4000;
        if(st[i].a>90) st[i].d+=2000;
        if(st[i].a>85&&st[i].y=='Y') st[i].d+=1000;
        if(st[i].b>80&&st[i].x=='Y') st[i].d+=850;
    }
    int max=1;
    for(int i=2;i<=n;i++)
        if(st[i].d>st[max].d) max=i;
    cout<

1305.选数

 题目描述

已知n个整数x1,x2,...,xn,以及一个整数k(k

3+7+12=22;3+7+19=29;7+12+19=38;3+12+19=34.

现在请你计算出和为素数的一共有多少种?

样例输入

4 3

3 7 12 19 

样例输出

首先我们可以用全排列的方法,然后去重,除以k!

#include
using namespace std;
const int N=1e6+10;
int q[N],vis[N],a[N];
int sum=0;
int n,x;
int f(int n)
{
    if(n<2) return 0;
    for(int i=2;i<=n/i;i++)
        if(n%i==0) return 0;
    return 1;
}
void dfs(int u,int x)
{
    if(u==x)
    {
        int ans=0;
        for(int i=0;i>n>>x;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    dfs(0,x);
    int y=1;
    for(int i=1;i<=x;i++)
        y*=1;
    cout<

1358.相邻素数距离

 题目描述

素数相信大家都已经很熟悉了,今天我们来求相邻素数的距离。输入一个n,找到与n相邻的两个素数,两素数的距离就是之差的绝对值如果n是素数,那么他的相邻两个素数就是n本身。

有多组数据。

数据范围

1

样例输入

10

11

样例输出

4

#include
using namespace std;
int f(int n)
{
    if(n<2) return 0;
    for(int i=2;i<=n/i;i++)
        if(n%i==0) return 0;
    return 1;
}
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0) break;
        int l=n;
        int x,y;
        if(f(n)) cout<<0<=2;i--)
            {
                if(f(i))
                {
                    x=i;break;
                }
            }
            for(int i=n;;i++)
            {
                if(f(i))
                {
                    y=i;
                    break;
                }
            }
            cout<

1473.奇怪的排序

 题目描述

最近,Dr.Kong新设计一个机器人Bill。这台机器人很聪明,会做许多事情。唯独对自然数的理解和人类不一样,它是从右往左读解。比如,看到123的时候,会理解为321,让他比较23和15哪个大的时候,他说15大,比如29和30,他说29大。

给定Bill两个自然数A和B,让他将[A,B]之间的所有数按从小到大的顺序排序出来。你认为他会如何排序?

输入

第一行:N 表示有多少组测试数据。

接下来有N行,每一行有两个正整数A B 表示待排序元素的区间范围。 

数据范围

2<=N<=5

1<=A<=B<=200000

B-A<=50 

样例输入

2

8 15

22 39 

样例输出

10 8 9 11 12 13 14 15

30 31 22 32 23 33 24 34 25 35

26 36 27 37 28 38 29 39 

#include
#include
#include
using namespace std;
const int N=1e6+10;
int a[N];

int f(int n)
{
    int ans=0;
    while(n>0)
    {
        ans=ans*10+n%10;
        n/=10;
    }
    return ans;
}

bool cmp(int a,int b)
{
    return f(a)>t;
    while(t--)
    {
        memset(a,0,sizeof(a));
        int l,r;
        cin>>l>>r;
        for(int i=l;i<=r;i++)
            a[i]=i;
        sort(a+l,a+r+1,cmp);
        for(int i=l;i<=r;i++)
            cout<

1203.做幻方

 题目描述

Apple最近迷上了做幻方,Apple还是个中高手,只要你说一个奇数,就能够把N*N的幻方做出来,其实你比他做的更好,要求:每一行,每一列,还有两条斜线上的数字相等。

输入一个奇数,输入0结束。有多组数据。

样例输入

5

1

样例输出

11 18 25 2 9

10 12 19 21 3

4 6 13 20 22

23 5 7 14 16

17 24 1 8 15

#include
using namespace std;
const int N=1000;
int q[N][N];
int main()
{
    int n;
    while(cin>>n)
    {
        memset(q,0,sizeof(q));
        q[1][n/2+1]=1;
        for(int x=2;x<=n*n;x++)
        {
            int ans=0;
            int a,b;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(q[i][j]==x-1)
                    {
                        a=i,b=j;
                        ans++;
                        break;
                    }
                }
                if(ans>0) break;
            }
            if(a==1&&b!=n) q[n][b+1]=x;
            else if(b==n&&a!=1) q[a-1][1]=x;
            else if(a==1&&b==n) q[a+1][b]=x;
            else if(a!=1&&b!=n)
            {
                if(q[a-1][b+1]>0) q[a+1][b]=x;
                else q[a-1][b+1]=x;
            }
        }
            for(int i=n;i>=1;i--)
            {
                for(int j=1;j<=n;j++)
                {
                    if(n*n>=100)
                        printf("%3d ",q[i][j]);
                    else if(n*n>=10&&n*n<=100)
                        printf("%2d ",q[i][j]);
                    else if(n*n<10)
                        printf("%1d ",q[i][j]);
                }
                printf("\n");
            }
            printf("\n");
        }
        return 0;
}

你可能感兴趣的:(算法,算法,c++,图论)