牛客竞赛-新手上路-语法入门-选择结构.c

F 吃瓜群众

链接:https://ac.nowcoder.com/acm/contest/19304/F
来源:牛客网
 

题目描述

群众想要吃瓜,于是给你一个瓜让你切,但是作为考验

告诉你西瓜的重量,问你能否将这个西瓜分成两部分,每个部分都是偶数。

注意:这里说的是能否分成两部分,不是能否平均分成两部分
 

输入描述:

输入一行,包含一个整数weight,表示西瓜的重量1 <= weight <= 100

输出描述:

输出一行,见样例。

代码:

#include
int main()
{
    int weight;
    scanf("%d",&weight);
    if(weight%2==0&&weight!=2)
//分为都为偶数的两部分,即为:该数(2本身除外)可以被2整除
        printf("YES, you can divide the watermelon into two even parts.");
    else
        printf("NO, you can't divide the watermelon into two even parts.");
    return 0;
}

注意点:

最小可分为两偶数的weight是4,不是2!

H 小明的回答

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

总算到暑假了,小姐姐是非常的闲,所以想去找梅溪湖的小名玩,可是她从没去过梅溪湖,所以只能凭小名告诉她的地方走,每次只能向上下左右四个方向走1步。小姐姐的坐标为(0,0),小名在(a,b),小姐姐有点近视,小名也有点近视。所以到了(a,b)也不一定能和小名会面,不过还好,小姐姐最后找到了小名。小姐姐想要小名知道自己来一趟是多么不容易,所以在聊天的过程中小姐姐说自己为了到这里走了n步。小名,你觉得她说的可能是真话么。有可能就输出YES,否则输出NO(如果用random的话,小姐姐觉得你好像不在意她,明年暑假就不来了)

输入描述:

a,b,n(-1000<=a,b<=1000,a*b>0,1<=n<=2000)

输出描述:

"YES" or "NO"

代码:

#include
int main()
{
    int a,b,n;
    scanf("%d %d %d",&a,&b,&n);
    if((n>=a+b)&&((n-(a+b))%2==0))//步数至少应为a+b
    //且说出的步数与最少步数之差应为2的倍数
//因为假设走过(a,b)时没有发现小名
//再返回(a,b)时相当于进行了“往返跑”
//往返,则路程必定为偶数
        printf("YES");
    else
        printf("NO");
    return 0;
}

注意点:

见代码注释

J 判断闰年

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

判断一个整数n是否是闰年

输入描述:

输入一个整数n (1≤n≤20181 \le n \le 20181≤n≤2018)

输出描述:

是闰年输出"yes" 否则输出"no"

代码:

#include
int main()
{
    int n;
    scanf("%d",&n);
    if((n%4==0&&n%100!=0)||n%400==0)//闰年条件:
        //可以被四整除,但不可以被100整除
        //或可以被400整除
        printf("yes");
    else
        printf("no");
    return 0;
}

 注意点:

闰年判断条件:可以被4,但不可以被100整除 或 可以400整除

K 统计正负个数

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

输入10个整数,分别统计输出正数、负数的个数。

输入描述:

输入10个整数(范围-231~231-1),用空格分隔。

输出描述:

两行,第一行正数个数,第二行负数个数,具体格式见样例。

代码:

#include
int main()
{
    int posi=0,nega=0,i,a;
    for(i=0;i<10;i++)
    {
        scanf("%d",&a);
        if(a<0) nega++;
        else if(a>0)
            posi++;
    }
    printf("positive:%d\nnegative:%d",posi,nega);
    return 0;
}

思路: 

思路1(本代码采用):

不用数组,每输入一次,就判断一次。

思路2:

用数组存储输入的数,之后依次判断。

N 送分题

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

数据结构之神ccz又在出毒瘤数据结构了

神出了这样一个题:

给你三个数,在这三个数中间任意加*或者是+,然后可以随便打括号,只要这个表达式合法

比如说1 2 3可以得到:

  • 1+2*3=7
  • 1*(2+3)=5
  • 1*2*3=6
  • (1+2)*3=9

不能改变这三个数的原顺序

最大化表达式的值

输入描述:

输入三行,每行一个数

分别表示a,b,c

输出描述:

输出一行一个数表示答案

代码:

#include
int main()
{
    int a,b,c,n[6],i,k,max;
    scanf("%d %d %d",&a,&b,&c);
    n[0]=a+b+c;
    n[1]=a+b*c;
    n[2]=a*b+c;
    n[3]=a*(b+c);
    n[4]=(a+b)*c;
    n[5]=a*b*c;
    max=n[0];
    for(i=1;i<6;i++)
    {
        if(n[i]>max) max=n[i];
    }
    printf("%d",max);
    return 0;
}

思路:

本题就是列出所有情况,一一比较,找出最大值,无其他更简便方法。

P B是不是太迟了

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

众所周知,gplt选拔赛是在10月29号进行。那么大家在10月29号之前都可以训练自己的编程(为什么29号不能训练了呢,因为29号要睡懒觉^_^)。

想在,小金翻开了日历,他想知道今天还能不能训练,是不是太迟了。

输入描述:

输入一个字符串S(格式为yyyy/mm/dd),保证在2020年并且日期合法。

输出描述:

没有太迟,还有时间训练,则输出:
No. It's not too late.
如果太迟了,输出:
QAQ

代码:

#include
int main()
{
    char a[11];
    scanf("%s",&a);
    if(a[5]=='0')
        printf("No. It's not too late.");
    else if(a[6]>'0')
        printf("QAQ");
    else if(a[8]<'2')
        printf("No. It's not too late.");
    else if(a[9]=='9'||a[8]=='3')
        printf("QAQ");
    else printf("No. It's not too late.");
    return 0;
}

思路:

思路1(本代码采用):

严格按照题目要求,输入数据类型为字符串,一个一个位置来判断(不推荐,太麻烦)

思路2:

非%s输入,而是%d输入年月日,将‘/’作为格式控制(即""里面)的一部分

scanf("%d/%d/%d",&y,&m,&d);
if(m>10||(m==10&&d>=29))
    printf("QAQ");
else     printf("No. It's not too late.");

Q 前天是哪天

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

给定公元2000年到公元3000年之间的某一天,请你给出该天的前天是哪一天.

输入描述:

输入在一个日期,格式如"yyyy-mm-dd",题目保证所有输入日期为合法日期。

输出描述:

在一行中输出日期,格式如"yyyy-mm-dd"。

备注:

注意日期格式,月份或者天数不足2位要补零。

代码:

#include
int main()
{
    int month(int m);
    int year(int y);
    int y,m,d;
    scanf("%d-%d-%d",&y,&m,&d);
    if(m==1&&d<3)//跨年时
    {
        y--;m=12;d=31+d-2;
    }
    else if(m==3&&d<3)//跨越到二月时
    {
        m--;d=year(y)+d-2;
    }
    else if(d<3)//跨月时
    {
        m--;d=month(m)+d-2;
    }
    else d=d-2;//不跨月时
    printf("%d-",y);
//月份,天数不足两位的要补0!
    if(m<10)
        printf("0%d-",m);
    else printf("%d-",m);
    if(d<10)
        printf("0%d",d);
    else printf("%d",d);
    return 0;
}
int year(int y)//判断闰年还是平年,并返回当年2月的天数
{
    if((y%4==0&&y%100!=0)||y%400==0)
        return 29;
    else return 28;
}
int month(int m)//判断大月还是小月,并返回当月,即m月(前天所在月份)的天数
{
    if((m<7&&m%2==0)||(m>8&&m%2==1))
        return 30;
    else return 31;
}

注意点:

  1. 注意前天是跨年,跨月到二月,跨月到大还是小月之间有所区别。
  2. 月份,天数不足2位时,则记得补零。

思路:

思路1(本代码采用):

写一个判断闰年的函数,返回2月天数;写一个判断大小月的函数,返回"前天"所在月的天数。分情况计算

思路2:

定义一个数组,提前储存好平年时的各月份的天数,判断为闰年时则将二月的天数替换为29,判断需要跨月时,将月数对应值减一,当月天数则为储存在数组中的对应的天数。其余计算部分与本代码基本一致。(此思路写出的代码较为简单,不易出错,推荐采用)

T 排队取水

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

羊村的供水系统搞砸了,隔壁牛村捐赠的的矿泉水刚刚送达,村长让喜羊羊们排队领水,已知有n个羊村村民正在排队取水,懒羊羊不知道他在队伍的具体哪个位置,但他知道有不少于a个人在他前面,有不多于b个人在他后面,你能帮忙计算一下懒羊羊有多少个可能的位置吗?

输入描述:

输入一行包含三个整数n,a,b

0<= a,b < n <= 100

输出描述:

输出一行包含一个整数表示可能的位置数

代码:

#include
int main()
{
    int a,b,n;
    scanf("%d %d %d",&n,&a,&b);
    if(a+b>=n-1)
//如果此处是n也可以ac,但从实际意义来看,应该是n-1,而不是n
    //因为当a+b==n-1(除懒洋洋自己以外的总人数)时
    //刚好处于一个临界位置,n-a==b+1
//当a+b>n-1时,结果取决于:懒洋洋前面至多有多少人,即a
    //因为此时,“懒洋洋后至少有b人”这一条件必定会满足
//相反,当a+b

思路:

思路1:

由题意,至少有a个人在前面,至多有b个人在后面,当a+b>=n-1(即除自己以外的所有人)时,可以在的位置取决于a(最多前面有几人);否则取决于b(自己后面最多有几人) [具体思路见代码注释]

思路2:

因为输出结果需要同时满足:前面至少有a人,后面至多有b人。因此将条件分开后,所分别得出的结果的最小值,一定时严格同时符合两个条件的。所以可以直接输出(n-a)与(b+1)之间的最小值,略去判断部分。

U 可编程拖拉机比赛

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

“这个比赛,归根结底就是控制一个虚拟的小拖拉机跑完整个赛道。一般一场比赛会有 9 个到 13 个赛道,最后看能跑完多少个赛道。”
通常在一场可编程拖拉机比赛中,分别会有实际参赛队伍数 10%、20%、30% 向下取整的队伍获得金、银、铜牌,其余队伍获得荣誉提名,俗称“铁牌”。
但是主办方往往会多准备一些奖牌,那么在发奖牌的时候会按照比例向上取整发出的奖牌以减少浪费,就会有一些原本获得银牌的队伍获得了金牌。
现在给出一个赛区的规模,也就是这个赛区的实际参赛队伍数,小 Q 同学想知道有多少队伍的奖牌会由银变金、由铜变银、由铁变铜。
 

输入描述:

输入只有一行,包含一个整数 n (10 <= n <= 1000),表示实际参赛队伍数。

输出描述:

输出一行,包含三个由空格分隔的整数,分别表示奖牌会由银变金、由铜变银、由铁变铜的队伍数。

代码:

#include
#include
int main()
{
    int n,a,b,c;
    scanf("%d",&n);
    //银升金
    if(n*0.1==floor(n*0.1))//本身为整数,没有多余名额
        a=0;
    else a=1;//否则多出一个名额,用于升银升金
    //铜升银
    if(n*0.2==floor(n*0.2))
        b=a;//因为前一个阶段升段,而导致银牌多出的数量为a
    else b=a+1;//因为n*0.2不为整数,而额外又多了1个名额
    //铁升铜
    if(n*0.3==floor(n*0.3))
        c=b;//因为前两个阶段的升段,而导致铜牌多出的数量为b
    else c=b+1;//因为n*0.3不为整数,而额外多出了1个名额
    printf("%d %d %d",a,b,c);
    return 0;
}

思路:

思路1(本代码采用):

每个类型奖牌至多分别比各自原本计划名额多1,当且仅当向上向下取整所得值一致,即结果本身为整数时,才不会比原本计划多1。判断部分从结果是否为整数入手。

思路2:

直接计算:

原本计划(向下取整):可以直接进行整数乘除计算,结果会自动舍弃小数部分,得计划名额

实际名额(向上取整):

        法1:写一个向上取整的函数:

int qvzheng(int a,int b)
{
    if(a%b==0) return(a/b);
    else return(a/b+1);
}

        法2:因为本题n为整数,所以可以通过+9后向下取整即可:

//金牌数
int aa=(a+9)/10;
//银牌数
int bb=(2*n+9)/10;
//铜牌数
int cc=(3*n+9)/10;

最后结果直接计算即可。

V [NOIP2004]不高兴的津津

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因为其它事不高兴,并且她的不高兴不会持续到第二天。请你帮忙检查一下津津下周的日程安排,看看下周她会不会不高兴;如果会的话,哪天最不高兴。

输入描述:

包括七行数据,分别表示周一到周日的日程安排。每行包括两个小于10的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。

输出描述:

包括一行,这一行只包含一个数字。如果不会不高兴则输出0,如果会则输出最不高兴的是周几(用1, 2, 3, 4, 5, 6, 7分别表示周一,周二,周三,周四,周五,周六,周日)。如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。

代码:

#include
int main()
{
    int a[7],b[7],i,re=0,h=0;
    for(i=0;i<7;i++)
    {
        scanf("%d %d",&a[i],&b[i]);
    }
    for(i=0;i<7;i++)
    {
        if(a[i]+b[i]>8)
        {
            if(a[i]+b[i]>h)
            {
                re=i+1;//注意实际对应星期为 数组的序号+1
                h=a[i]+b[i];
            }
        }
        else continue;
    }
    printf("%d",re);
    return 0;
}

思路:

思路1(本代码采用):

两个数组,表示分别学校的课与妈妈安排的课的时间,用 数组序号+1 表示星期几,没有遇到超过8小时时,默认re=0;知道超过8小时时,re存储下当 数组序号+1(星期几),如果遇到时间更长的,则re储存的内容更替,否则不变。其中为方便判断本次循环中,津津的学习时间是否超过当前已记录的最长学习时间,另设一变量h,用于存储最多的学习时间。

思路2:

可可以不用数组进行存储,在循环中输入即可,每输入一次,便进行一次判断,循环7次即可。此思路可以令 i 初始值为1,直接表示星期几。

W [NOIP2008]ISBN号码

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。
你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。

输入描述:

只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。

输出描述:

共一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。

代码:

#include
int main()
{
    int n,i;
    char a[14];
    scanf("%s",a);
    n=((a[0]-48)*1+(a[2]-48)*2+(a[3]-48)*3+(a[4]-48)*4+(a[6]-48)*5+(a[7]-48)*6+(a[8]-48)*7+(a[9]-48)*8+(a[10]-48)*9)%11;
    if(n==10) n='X';
    else n=n+48;
    if(n==a[12])
        printf("Right");
    else
    {
        for(i=0;i<12;i++)
            printf("%c",a[i]);
        printf("%c",n);
    }
    return 0;
}//虽说知道这个代码很烂,但不想改了,有时间再改

思路:

可以用字符数组输入,计算最后一位数时注意将所有数字字符减去48后再计算,注意将n==10的情况与其他情况分开,如果n!=10,记得在把48加回去,否则会影响下面"n是否等于最后一位数字"的判断。如果结果不是right,则输出时应按%c格式输出。

n的计算部分可以用循环来实现,不用一个一个手动输入,代码如下:

for(i=0,k=1,n=0;i<13;i++)
{
    if(a[i]=='-') continue;
    else n=n+(a[i]-48);
    k++;
}

或者可以再定义一组数组,利用上述循环,同时将‘数字字符’转化为的‘数字’存储进去,方便之后的判断与输出,以防因为忘记对输出时的n加48(n!=10时)导致输出错误。

你可能感兴趣的:(c语言)