程序设计语言综合设计(第 3 章)

  • 第 3 章
    • 3_On_the_road Vayh_E 上分之路
    • 3_The_size 不同进制数字比较大小
    • 3_Variety_String Vayh_E 的百变字符串
    • 3_The_mystery_of_time Vayh_E 时间之谜
    • 3_Dominoes 多米诺骨牌
    • 3_Encrypted_note Vayh_E 的加密纸条
    • 3_Soldiers 士兵布阵

第 3 章

3_On_the_road Vayh_E 上分之路

实验任务

  Vayh_E 学姐经常在codeforces 上刷题,但是他状态很不稳定,不能持续上分,经常打着打着突然变成辣鸡咸鱼,跌倒低谷,一战绿名。(都掉到绿了你还敢说啊,辣鸡)
所以学姐想要知道她最长连续几次codeforces 没有掉分。给出每次codeforces 比赛后的成绩,让你帮学姐算算连续几次成绩组成的序列是最长的非降的连续数串。(扯了那么远)

数据输入

  第一行一个正整数n(1<=n<=1000),表示次数为n。

  第二行为n 个整数,第i 个数表示第i 次codeforces 比赛后的分数。

数据输出

  输出一个数,表示连续多少次分数没有掉。

样例

输入示例

6
5 1 1 5 4 6

输出示例

3

Hint

  从第二次到第四次,1 到1 再到5,连续3 次非降。


Code

#include 
int main (void)
{
    short n,i;
    scanf("%hd",&n);
    if (n==1)       //若输入只有一个整数,则输出1,结束程序
    {
        printf("1\n");
        return 0;
    }
    short t[2],temp=1,max=-1,num=1;     //t[2]为两个变量,交替存储数据
    scanf("%d",&t[0]);      //先读取一个数t[0]
    for (i=2;i<=n;i++)
    {
        scanf("%hd",&t[temp]);      //再读取一个数t[1] 
        if (t[temp]>=t[!temp])      //若t[1]大于等于t[0],则连续不下降
        {
            num++;          //数列长度+1
            if (num>max)    //如果数列长度大于最大长度
               max=num;     //更新最大长度
        }
        else
            num=1;          //否则数列长度重新从1开始
        temp=!temp;         //此时t[0]里的数已经没用了,于是下一次循环用t[0]存储新的数据。
    }
    printf("%d\n",max);
    return 0;
}

3_The_size 不同进制数字比较大小

实验任务

  这题是要求比较两个数的大小,但是两个数的进制是不一样的。
  数的进制和每一位的数字已知,比较两数的大小。
  (人家编不出故事了,就卖个萌好不好(。•ˇ‸ ˇ•。))
  (让你编故事你不会,整天打些有的没的)

数据输入

  第一行两个正整数n1 和m1,表示第一个数为m1 进制,有n1 位。
  第二行为n1 个整数,第i 个数表示第n1-i+1 位上的数。
  第三行两个正整数n2 和m2,表示第二个数为m2 进制,有n2 位。
  第四行为n2 个整数,第i 个数表示第n2-i+1 位上的数。

数据输出

  比较这两个数的大小,第一个数大输出“>”,第一个数大输出“<”,两数一样大输出“=”。

样例

输入示例

2 2
1 1
2 3
1 0

输出示例

=

Hint

  2 进制的11 和3 进制的10 相等


Code

#include 
int main (void)
{
    int n1,n2,m1,m2,i,num1=0,num2=0,t;
    scanf("%d%d",&n1,&m1);
    for (i=1;i<=n1;i++)
    {
        scanf("%d",&t);         //读取当前位
        num1=num1*m1+t;         //之前位乘以进制数加上当前位
    }
    scanf("%d%d",&n2,&m2);
    for (i=1;i<=n2;i++)
    {
        scanf("%d",&t);
        num2=num2*m2+t;
    }
    if (num1==num2)
       printf("=\n");
    else if (num1>num2)
         printf(">\n");
    else
        printf("<\n");

    return 0;
}

123 (3) = ( ( (0*3+1)*3+2)*3+3) = 18 (10)


3_Variety_String Vayh_E 的百变字符串

实验任务

  vayh 学姐最喜欢跟别人玩变换字符串的游戏了,又考验眼力,又锻炼大脑
  (又开始乱编故事了!)。
  (不管嘛!人家就是要玩!你咬我啊!(┙>∧<)┙へ┻┻)。
  接下来她会给你一个初始字符串,然后给你m 次变换。
  每次告诉你两个字符,你将字符串里的两种字符相互替换就行辣,简单不?!
  (zz 题( ̄y▽ ̄)~*捂嘴偷笑)

数据输入

  第一行输入两个整数n 和m,代表输入的字符串长度为n,然后要经历m 次转换。
  第二行输入一个长度为n 的字符串。
  接下来m 行,每次输入两个字母a 和b,则将字符串中所有a 字母替换成b 字母,b 字母替换成a 字母。

数据输出

  输出最后的新字符串。

样例

输入示例

6 2
abcbad
a c
b d

输出示例

cdadcb

Hint

  第三行输入a c,则字符串变为cbabcd;


Code

#include 
int main (void)
{
    int n,m,i,j;
    char s[10010];
    scanf("%d %d",&n,&m);
    scanf("%s",s);
    for (i=1;i<=m;i++)
    {
        getchar();      //处理回车

        char a,b;
        a=getchar();
        getchar();      //处理空格
        b=getchar();
        for (j=0;j//遍历,替换
        {
            if (s[j]==a)
                s[j]=b;
            else if (s[j]==b)
                s[j]=a;
        }
    }
    printf("%s\n",s);
    return 0;
}

3_The_mystery_of_time Vayh_E 时间之谜

实验任务

  Vayh_E 学姐经常赖床(你还敢讲出来是吧?!),一觉睡到11 点(你早上没课的吗?!),有一天她睡觉的时候凭空开了个程序计算她睡了多久((→_→)传说中的人脑编译,手动运行嘛,你怎么不上天啊),看看自己到底多能睡。
  第二天她起床的时候她突然想知道自己前一天是几点睡的(想知道看电视剧看到几点是吧,没三点我都不信),可是她只知道现在几点,以及自己睡了多久,请你帮她算算她是几点睡的。

数据输入

  第一行输入一个字符串表示现在的时刻。
  第二行输入一个字符串表示睡了多久。
  (时间格式统一为xx:xx)

数据输出

  输出如输入格式的字符串代表入睡的时刻。

样例

输入示例

12:00
01:00

输出示例

11:00

#include 
int main (void)
{
    short hour,min,h,m;
    scanf("%hd:%hd",&hour,&min);    //hour,min为当前时间
    scanf("%hd:%hd",&h,&m);         //h,m为睡眠时间

    short hh,mm;    //hh,mm为起始时间
    mm=min-m;       //先算分钟
    short t=0;      //t用于处理小时退位
    if (mm<0)       //当睡眠分钟大于当前分钟
    {
        t=1;        //则小时需要退位
        mm=60-(-1*mm%60);   //起始分钟计算公式
    }
    hh=hour-h-t;    //计算小时
    if (hh<0)
        hh=24-(-1*hh%24);   //起始小时计算公式
    if (hh==24)
        hh=0;       //当小时为24时,需转换成00输出
    printf("%02d:%02d\n",hh,mm);
    return 0;
}

3_Dominoes 多米诺骨牌

实验任务

  今天真是风和日丽的一天(强行故事背景),vayh 姐姐无聊玩起了多米诺骨牌(woc 这是有多无聊啊= = ),她先将所有的牌按一条直线排好,然后将其中的一些牌同时推到(同时??这招叫是叫……台风嘛……(°□°;)),有的推向左边,有的推向右边(一定是闲的)。
  然后vayh 姐姐要来给大家出难题啦(就知道你没安好心),她想问你最后有多少牌没有被推倒。给出一个字符串代表n 张多米诺骨牌,字符代表它们的状态啊,“.”代表没被推,“R”代表被往右推,“L”代表被往左推。如:..R..L..则第三张牌被往右推,第六张牌被往左推。
  已知往右倒的牌会一直往右传导,呈多米诺骨牌效应,直到遇到往左倒的牌才不会再往右一直传导;往左倒的牌亦然。

数据输入

  第一行输入一个数n 代表有多少张多米诺骨牌。
  第二行输入一个长度为n 的字符串,每个字符代表每张多米诺骨牌的状态。

数据输出

  输出最后剩几张牌是站立的。

样例

输入示例

7
..R..L.

输出示例

3

输入示例

11
..L...R..L.

输出示例

4

Hint

  1,第3、4、5、6 张多米诺骨牌会倒下,第1、2、7 张牌会直立。
  2,第1、2、3、7、8、9、10 张多米诺骨牌会倒下,剩下的牌直立。

Code

#include 
int main (void)
{
    int n,i;
    char s[10010];
    scanf("%d",&n);
    scanf("%s",s);


    short ok_1=1,ok_2=0;    //初始化,当作s[0]=='L'
    int start=-1,end,sum=0;
    for (i=0;iif (s[i]=='L')
        {
            start=i; ok_1=1;
            if (ok_2 && (start-end-1)%2==1)     //如果之前出现过R且中间骨牌数为奇数
                sum++;      //则最中央骨牌会站立
            ok_2=0;     //处理过后,ok_2清零,以防在L之后再出现L导致重复计算
        }
        else if (s[i]=='R')
        {
            end=i; ok_2=1;
            if (ok_1)       //如果之前出现过L
            {
                sum+=end-start-1;   //计算站立骨牌数
                ok_1=0;    //处理过后,ok_1清零,以防在R之后再出现R导致重复计算
            }
        }
    }
    if (ok_1)   //如果ok_1==1;说明最后出现的字母是L
       sum+=n-start-1;      //则L之后的骨牌要计算在内
    printf("%d\n",sum);
    return 0;
} 

通过L和R出现的位置确定两字母中间的骨牌数

  • 当从L到R时,中间骨牌数即为站立骨牌数
  • 当从R到L时,中间骨牌数若为奇数,则最中间的骨牌是站立的。
  • 注意处理头尾边界情况。

3_Encrypted_note Vayh_E 的加密纸条

实验任务

  Vayh_E 学姐高中的时候很喜欢用英文传纸条(强行编故事!人家都是用QQ 的好不啦!),但是怕被别人知道纸条里的秘密(哦?什么秘密?我也想知道!!),他喜欢对纸条里面的内容进行加密。加密方式如下:
  他将里面的单词用1 个或多个“WUB”隔开,开头和结尾也可能有“WUB”。
  (Excuse me?这种加密也叫加密哦,傻子都看得出来好吗?? )
  (( >﹏<。) 干嘛lia,人家乐意嘛!!)

数据输入

  输入一个字符串(好随便哦,就酱紫而已嘛?)。

数据输出

  输出字符串里的内容,每个单词用一个空格隔开。

样例

输入示例

WUBWRONGWUBANSWERWUBWUB

输出示例

WRONG ANSWER

Code

#include 
int main (void)
{
    short ok=1;
    int i=0,k=0;
    char s[10010];
    scanf("%s",s);
    while(s[i]!='\0')
    {
        if (s[i]=='W' && s[i+1]=='U' &&  s[i+2]=='B')   //如果遇到字符串“WUB”        
        {   //如果“WUB”不是第一个出现,也不是最后一个出现,且不是连续出现
             if (i!=0 && s[i+3]!='\0' && ok )   
                s[k++]=' '; //赋值一个空格
             i=i+3; ok=0;   //ok清零,用于是否连续出现“WUB”的判断
        }
        else
        {
            s[k++]=s[i];    //不是“WUB”,就直接赋值当前字符
            i++; ok=1;
        }
    }
    while (s[--k]==' ');    //k从字符串末尾递减,直到s[k]不是空格
    for (i=0;i<=k;i++)
        printf("%c",s[i]);  //输出字符串
    printf("\n");
    return 0;
} 

3_Soldiers 士兵布阵

实验任务

  A 国与B 国开战,A 国的军队正在紧张地列阵。将军把军队分成了n 个小军团,并把n个军团排成了一条直线,并进行n 种操作。

  (等等,这题的画风怎么跟别的不太一样!)

  (哎呀你管我啦,烦死了!!!(╬▔皿▔))

  先告诉你一开始每个军团

  “query”操作:输入两个数left 和right,求出[left,right]这个区间内目前所有的军团总共有多少士兵。

  “reverse”操作:输入两个数left 和right,将[left,right]这个区间反转一遍,比如把{1,2,3,4,5}这个数列在[2,5]反转即为{1,5,4,3,2}。

  “change”操作:输入两个数a 和b,将这整条直线上所有士兵数量为a 的军队的士兵数改为b

  “sort”操作:输入两个数left 和right,将[left,right]这个区间内的军团按士兵数从少到多排序一遍,比如把{1,5,3,4,2}这个数列在[2,4]排序即为{1,3,4,5,2}。

  “output”操作:输出n 个数,即当前整条直线上每个军团各有多少士兵。

数据输入

  第一行输入两个正整数n 和m 。
  第二行输入n 个整数,代表一开始直线上每个军团各有多少士兵。
  接下来m 行,每行输入一个字符串表示m 个操作,之后操作如上。

数据输出

  当遇到输入为“query”和“output”时按要求输出。

样例

输入示例

5 5
1 5 2 4 3
sort 2 4
reverse 1 3
query 2 5
change 2 7
output

输出示例

11
4 7 1 5 3

Hint

  一开始的数列为1 5 2 4 3
  第一次操作,在2 到4 进行sort,数列为1 2 4 5 3。
  第二次操作,在1 到3 进行reverse,数列为4 2 1 5 3。
  第三次操作,在2 到5 进行query,输出[2,5]区间的和,则输出11。
  第四次操作,把所有2 变为7,数列为4 7 1 5 3。
  第五次操作,输出整个数列,则输出4 7 1 5 3。


Code

#include 
#include 
#include 
using namespace std;
int main (void)
{
    int a[10010];
    int i,j,k,t,n,m,left,right;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for (i=1;i<=m;i++)
    {
        char s[8];
        scanf("%s",s);
        if (strcmp(s,"query")==0)   //区间求和输出
        {
            int sum=0;
            scanf("%d%d",&left,&right);
            for (j=left;j<=right;j++)
                sum+=a[j];
            printf("%d\n",sum);
            continue;    
        }
        if (strcmp(s,"reverse")==0) //区间反转
        {
            scanf("%d%d",&left,&right);
            for (j=left,k=right;jcontinue;
        }
        if (strcmp(s,"change")==0)  //特定数字替换
        {
            scanf("%d%d",&left,&right);
            for (j=1;j<=n;j++)
                if (a[j]==left)
                   a[j]=right;          
            continue;
        }
        if (strcmp(s,"sort")==0)    //区间排序
        {
            scanf("%d%d",&left,&right);
            sort(a+left,a+right+1);     //a+left为起点,right-left+1为排序个数
            continue;
        }
        if (strcmp(s,"output")==0)  //区间输出
        {
            printf("%d",a[1]);
            for (j=2;j<=n;j++)
                printf(" %d",a[j]);
            printf("\n");
            continue;       
        }
    }

    return 0; 
} 

你可能感兴趣的:(题解)