PTA天梯赛L1刷题总结(二)10分题型


从这里开始,题目通常都是先给N,然后给出N行数据,虽然题目中看上去输出样例是一起输出,但是我们在编译器里可以是针对每一个样例给出结果(不用把示例都输入后再输出结果),意味着不需要用数组储存(或者使用结构体),可以节省代码量。

一般情况下,题目还会要求行尾不能有空格,那么我们可以在输出时分两种情况,如if(i==n)时 输出xxx, else 输出xxx 以及空格。 测试时注意使用英文的标点符号 最好在变量需要时再进行初始化,这样也比较方便(但是好像Code Blocks不支持这样操作,需要一开始就定义变量)。 在计数时注意赋初始值( 一般为0),否则该变量数值不确定

接下来说说10分题出现的题型(旁边是题号)

  1. 给一个整数,输出每一位上的数字 7

L1-007 念数字 (10分) 输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。

  • 如果是过去的思维,通常会采用C语言的switch-case结构,先读入整数,再获取每一位上的数字,用switch-case结构来读出每一位的拼音

  • 如果是用更聪明的想法,其实数字和拼音是存在一个一一映射的关系(hash),那么可以用读入字符串的方式读入输入示例。如果是char型数组的话,可以用二维数组charm定义,因为二维数组中的每个一维数组都存储着拼音,当然如果使用string数组就更方便了。或者使用STL容器的map来做也很快(后面大题再说)。

下面以三种做法为例进行对比 1)读入整型法 这里涉及到如何获取每一位的数字的做法。很容易理解,以106为例,106%10,余数为6,即个位,然后106/10后再取余,循环的终止条件在于/10之后为0。这样依次获取的数字是从右往左读的,所以在输出时需注意。在这里我的做法是把获取的每一位数存入数组,在倒序输出。

#include <stdio.h>
#include <stdlib.h>

void num(int s)
{
switch (s)
{
case 1:
printf("yi");break;
case 2:
printf("er");break;
case 3:
printf("san");break;
case 4:
printf("si");break;
case 5:
printf("wu");break;
case 6:
printf("liu");break;
case 7:
printf("qi");break;
case 8:
printf("ba");break;
case 9:
printf("jiu");break;
case 0:
printf("ling");break;
}
}
int main()
{
int n,i,j;
int a[100]={0};
scanf("%d",&n);
if(n<0)
  {
       printf("fu ");
       n*=(-1);
  }
   i=0;
   while(n/10)
  {
       a[i++]=n%10;
       n/=10;
  }
   a[i]=n;
   for(j=i;j>=0;j--)
  {
       if(j==0) num(a[j]);
       else
      {
           num(a[j]);
           printf(" ");
      }
  }
return 0;
}

2)二维数组法 len = strlen(s);获取字符数组的长度 s[i]-'0'获得的就是该字符对应的整数 如'6'-'0'=6 另外在if-else如果只有两种情况(非此即彼),那么就可用xxx?a:b xxx表示判断条件,如果满足则执行a,否则执行b。这样来简化写法

#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main() {
   char a[10][10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
   char s[1000];
   scanf("%s",s);
   int len=strlen(s);
   int flag = s[0] == '-' ? 1 : 0;
   if(flag == 1)
      printf("fu");
   for(int i = flag; i < len; i++)
  {
       if(i == 0)
      {
           printf("%s",a[s[i]-'0']);
           continue;
      }
       
       printf(" %s",a[s[i]-'0']);
  }
   return 0;
}

3)string数组法 在很多题目中,我们会采用标志位flag来标记,通常初始化为0,如果满足某条件标记为1,这样可以容易地判断是否满足某一条件。在这道题中,如果a[0]=='-',就说明这个数是负数,输出"fu",注意在读入string类型的a时,应该用的是英文的单引号'',而非双引号.

#include <iostream>
#include <string>

using namespace std;

int main()
{
   string s[10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
   string a;
   int h;
   int i,flag;
   flag=0;
   cin>>a;
   if(a[0]=='-')
  {
       flag=1;
       cout<<"fu ";
  }
   for(int i=flag;a[i]!='\0';i++)
  {
        h = a[i]-'0';
       if(i<a.length()-1)
           cout<<s[h]<<" ";
       else
            cout<<s[h];
  }

   return 0;
}

2.排序 10

具体排序方法有很多,这里介绍STL容器中的sort,注意要加头文件 #include < algorithm >基本用法是定义了数组之后,sort(数组的起始位置,结束的下一个位置,cmp),第三个参数不加时默认时从小到大排序,否则需要自定义一个cmp函数,规定排序的顺序

  • L1-010 比较大小 (10分) 要求将输入的任意3个整数从小到大输出。

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
   int a[3];
   cin>>a[0]>>a[1]>>a[2];
   sort(a,a+3);
   for(int i=0;i<3;i++)
  {
       if(i<2)
           cout<<a[i]<<"->";
       else cout<<a[i];
  }
   return 0;
}

3.格式化输出 不足补充 靠右 8 18 37(分类讨论)

关于格式化输出,在上一节已作讨论,在这里来说以下靠右的做法,例如 左对齐-%10d 右对齐%10d。数字宽度为10,若不足10,在左边补足空格

  • 以L1-008 求整数段和 (10分)为例 首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X。

这道题需要特别注意的是换行,可以用一个变量cnt来递增,若cnt%5==0说明此时该换行,另外一个测试点在于如果最后一个数不是在最后一行最后一个位置,不需要换行

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
   int m,n,flag,sum;
   cin>>m>>n;
   sum=flag=0;
   for(int i=m;i<=n;i++)
  {
       printf("%5d",i);
       flag++;
       if(flag%5==0&&i!=n)
           printf("\n");
       sum+=i;
  }
   cout<<endl;
   cout<<"Sum = "<<sum;
   return 0;
}

4.简单计算 阶乘计算(嵌套循环) 13 31 40

以L1-031 到底是不是太胖了 (10分)为例 说此题的原因在于 abs(x) 要加头文件 #include x必须为整数 浮点型用math.h下的fabs() 注意在if 的时候不要把公共部分放在else中,否则不会输出公共内容

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
   int n,W,w,H;
   cin>>n;
   while(n--)
  {
       cin>>H>>W;
       w=(H-100)*1.8;
       if(fabs(W-w)<w*0.1)
           cout<<"You are wan mei!"<<endl;
       else if(W>w)
           cout<<"You are tai pang le!"<<endl;
       else
           cout<<"You are tai shou le!"<<endl;
  }
   return 0;
}

5.简单题 22 47 53 61 不多说 6.判断素数 28 判断素数需要用到sqrt()求平方根缩小循环的范围,否则可能会超时,注意加上头文件<math.h> L1-028 判断素数 (10分)

#include <iostream>
#include <math.h>
#include <cstdio>
using namespace std;

int main()
{
   int i,j,n,m;
   cin>>n;
   for(i=0;i<n;i++)
  {
        int flag=0;
        cin>>m;
       for(j=2;j<=sqrt(m);j++)
      {
           if(m%j==0)
          {
               flag=1;
               break;
          }
      }
           if(flag==1||m==1)
               cout<<"No"<<endl;
           else if(flag==0)
               cout<<"Yes"<<endl;      
  }
   return 0;
}

7.达到某条件即break 41 一般达到某条件则用break退出循环

L1-041 寻找250 (10分) 输入在一行中给出不知道多少个绝对值不超过1000的整数 在一行中输出第一次出现的"250"是对方扔过来的第几个数字(计数从1开始)

这样的情况就是不能够知道到底扔来多少数,这时候就可以用while(1)不断接收数字,一旦满足此数为250即退出循环

#include <iostream>
#include <string>
#define N 10010
using namespace std;

int main()
{
   int i;
   int m=0;
   do
  {
       cin>>i;
       if(i==250)
      {
           cout<<m+1;
           break;
      }
       m++;
  }while(1);

   return 0;
}

8.根据题意求解 55 63

以L1-055 谁是赢家 (10分)为例 每次安排两位艺人表演,他们的胜负由观众投票和 3名评委投票两部分共同决定。如果一位艺人的观众票数高,且得到至少 1名评委的认可,该艺人就胜出;或艺人的观众票数低,但得到全部评委的认可,也可以胜出。数字 0 代表投票给 a,数字 1 代表投票给 b,其间以一个空格分隔。 这题思路不难,用几个变量存储一下观众和评委得票数,根据题意进行描述即可

#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
   int i,pa,pb,a,b,c,qa,qb;
   cin>>pa>>pb;
   qa=qb=0;
   for(i=0;i<3;i++)
  {
        cin>>a;
        a==0?qa++:qb++;
  }
   if((pa>pb&&qa>=1)||(pa<pb&&qa==3))
       cout<<"The winner is "<<"a"<<": "<<pa<<" + "<<qa;
   else
       cout<<"The winner is "<<"b"<<": "<<pb<<" + "<<qb;
   return 0;
}

评论

此博客中的热门博文

探索2025年的数字生活与个人成长

pta天梯赛l1刷题总结(三)15分题型