头像

且行且珍惜_9


访客:2804

离线:1小时前



题目描述

给定一个不超过 9 位的整数,你应该用传统的中文方式阅读它.

如果是负数,则先输出 Fu。

例如,-123456789 读作 Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu。

注意:零(ling)必须按照中国传统正确处理。

例如,100800 读作 yi Shi Wan ling ba Bai。

输出格式

输出给定数字的中文读法,注意结尾不能有多余空格。

样例

输入样例1:
-123456789
输出样例1:
Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu
输入样例2:
100800
输出样例2:
 yi Shi Wan ling ba Bai

算法


C++ 代码

#include<bits/stdc++.h>
using namespace std;
string dan[]={"Ge","Shi","Bai","Qian","Wan","Yi"};
string Num[]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};

string convertNum(string str)
{
    string ans;
    if(str[0]=='0')
     { return "ling"; }

     if(str[0]=='-')
      {
          ans="Fu ";
          str.erase(0,1);
      }
      int len=str.length();
       int i=0;
       while(len)
       {
           int zeroCnt=0;
           bool zero=false;

            for (int j = (len - 1) % 4; j >= 0; j--) { // 枚举个十百千
            //获取最高位的数字
            int pos = str.length() - len;
            int num = str[pos] - '0';

             if (num > 0) { 
                if (zero) {  //如果上一位是0
                    ans += "ling ";  
                    zero = false; 
                } 
                //输出数字+单位
                ans += Num[num] + ' ';
                if (j != 0) ans += dan[j] + ' ';
            }
            else { //如果当前数字为0
                zeroCnt++;
                zero = true;
            }
            len--;
        }
        //位数大于4位,且该段不全为0,输出亿或者万 
        if (len / 4 > 0  && zeroCnt != 4) ans += dan[3 + len / 4] + ' ';
    }
    ans.pop_back();
    return ans;
}

int main()
{
    string str;
    cin>>str;
    str=convertNum(str);
    cout<<str;
    return 0;
}




题目描述

键盘上有些按键已经损坏了。

当你输入一些句子时,与坏掉的按键相对应的字符将不会出现在屏幕上。

现在给定你应该键入的字符串以及你实际键入的字符串,请找出哪些按键坏了。

输入格式

输出格式

第一行包含应该键入的字符串。

第二行包含实际键入的字符串。

两个字符串中都只包含大小写英文字母,数字以及 _(表示空格)。

样例

输入样例:
7_This_is_a_test
_hs_s_a_es
输出样例:
7TI

算法

利用简单bool数组,标记差异字符,最后输出即可。

C++ 代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s1,s2;
    cin>>s1>>s2;
    bool st[200]={0};
        s2+='#';
    for(int i=0,j=0;i<s1.size();i++)
     {
        char x=toupper(s1[i]),y=toupper(s2[j]);
         if(x==y)j++;
         else{
              if(!st[x])
              cout<<x;
               st[x]=true;
         }
     }
    return 0;
}




题目描述

给定一个 k+1 位的正整数 N,写成 ak⋯a1a0 的形式,其中对所有 i 有 0≤ai<10 且 ak 大于 0。

N 被称为一个回文数,当且仅当对所有 i 有 ai=ak−i。

零也被定义为一个回文数。

非回文数也可以通过一系列操作变出回文数。

首先将该数字逆转,再将逆转数与该数相加,如果和还不是一个回文数,就重复这个逆转再相加的操作,直到一个回文数出现。

如果一个非回文数可以变出回文数,就称这个数为延迟的回文数。

给定任意一个正整数,本题要求你找到其变出的那个回文数。

输出格式

对给定的整数,一行一行输出其变出回文数的过程。

每行格式如下:

A + B = C
其中 A 是原始的数字,B 是 A 的逆转数,C 是它们的和。A 从输入的整数开始。

重复操作直到 C 在 10 步以内变成回文数,这时在一行中输出 C is a palindromic number.;

或者如果 10 步都没能得到回文数,最后就在一行中输出 Not found in 10 iterations.。

样例

输入样例1:
97152

输出样例1:
97152 + 25179 = 122331
122331 + 133221 = 255552
255552 is a palindromic number.

输入样例2:
196
输出样例2:
196 + 691 = 887
887 + 788 = 1675
1675 + 5761 = 7436
7436 + 6347 = 13783
13783 + 38731 = 52514
52514 + 41525 = 94039
94039 + 93049 = 187088
187088 + 880781 = 1067869
1067869 + 9687601 = 10755470
10755470 + 07455701 = 18211171
Not found in 10 iterations.

算法

高精度加法,利用vector数组实现。

C++ 代码

#include<bits/stdc++.h>
using namespace std;
bool check(vector<int> A)
{
    for(int i=0,j=A.size()-1;i<j;i++,j--)
           if(A[i]!=A[j]) return false;
              return true;
}
vector<int> add(vector<int> A,vector<int> B)
{
    vector<int> C;
    for(int i=0,t=0;i<A.size()||i<B.size()|| t;i++)
    {
         if(i<A.size())t+=A[i];
         if(i<B.size())t+=B[i];
           C.push_back(t%10);
           t/=10;
    }
    return C;
}
void print(vector<int> A)
{
    for(int i=A.size()-1;i>=0;i--)cout<<A[i];
}
int main()
{
       string a;
      cin>>a;
     vector<int> A;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
       for(int i=0;i<10;i++)
       {
             if(check(A)) break;
              vector<int> B(A.rbegin(),A.rend());

            print(A),cout<<" + ",print(B),cout<<" = ";
              A=add(A,B);
            print(A),cout<<endl;
       }
       if(check(A)) print(A), cout<<" is a palindromic number."<<endl;
       else cout<<"Not found in 10 iterations.";
    return 0;
}




题目描述

如果你是哈利波特的粉丝,你就会知道魔术世界有其自己的货币体系。

正如海格对哈利解释的那样:“17 个银镰刀(Sickle)可以换 1 个帆船(Galleon),29 个克努特(Knut)可以换 1 个银镰刀。”

你的工作是编写一个计算 A+B 的程序,其中 A 和 B 以 Galleon.Sickle.Knut 的标准形式给出(Galleon 是一个范围在 [0,107] 的整数,Sickle 是一个范围在 [0,17) 的整数,Knut 是一个范围在 [0,29) 的整数)。

输出格式

按照题目所述标准格式,输出 A+B 的结果。

样例

输入样例:
3.2.1 10.16.27
输出样例:
14.1.28

算法

水题一道,暴力即可轻松处理。

C++ 代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b,c,d,e,f;
    scanf("%d.%d.%d %d.%d.%d",&a,&b,&c,&d,&e,&f);
        a+=d,b+=e,c+=f;
        b+=c/29,c%=29;
        a+=b/17,b%=17;
        printf("%d.%d.%d",a,b,c);
        return 0;
}




题目描述

PAT 准考证号由 4 部分组成:

第 1 位是级别,即 T 代表顶级;A 代表甲级;B 代表乙级;
第 2∼4 位是考场编号,范围从 101 到 999;
第 5∼10 位是考试日期,格式为年、月、日顺次各占 2 位;
最后 11∼13 位是考生编号,范围从 000 到 999。
现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。

输出格式

对每项统计要求,首先在一行中输出 Case #: 要求,其中 # 是该项要求的编号,从 1 开始;要求 即复制输入给出的要求。随后输出相应的统计结果:

类型 为 1 的指令,输出格式与输入的考生信息格式相同,即 准考证号 成绩。对于分数并列的考生,按其准考证号的字典序递增输出(题目保证无重复准考证号);
类型 为 2 的指令,按 人数 总分 的格式输出;
类型 为 3 的指令,输出按人数非递增顺序,格式为 考场编号 总人数。若人数并列则按考场编号递增顺序输出。
如果查询结果为空,则输出 NA。

样例

输入样例:
8 4
B123180908127 99
B102180908003 86
A112180318002 98
T107150310127 62
A107180908108 100
T123180908010 78
B112160918035 88
A107180908021 98
1 A
2 107
3 180908
2 999

输出样例:
Case 1: 1 A
A107180908108 100
A107180908021 98
A112180318002 98
Case 2: 2 107
3 260
Case 3: 3 180908
107 2
123 2
102 1
Case 4: 2 999
NA

算法

利用了vector和hash表来存储字符串,按照题目要求输出即可

C++ 代码

#include<bits/stdc++.h>
using namespace std;
const int N=10010;
struct person{
    string id;
    int score;
}p[N];
bool cmp(person a,person b)
{
    if(a.score!=b.score)
      return a.score>b.score;
      else return a.id<b.id;
}
int main()
{
    int m,n;
    cin>>m>>n;
    for(int i=0;i<m;i++)
    cin>>p[i].id>>p[i].score;
      for(int k=1;k<=n;k++)
      {
           string t,c;
           cin>>t>>c;
        printf("Case %d: %s %s\n",k,t.c_str(),c.c_str());

          if(t=="1")
          {
              vector<person> pon;
              for(int i=0;i<m;i++)
                if(p[i].id[0]==c[0])
                pon.push_back(p[i]);

                 sort(pon.begin(),pon.end(),cmp);
                   if(pon.empty()) cout<<"NA"<<endl;
                   else
                       for(auto p:pon)
                        printf("%s %d\n",p.id.c_str(),p.score);
            }
            else if(t=="2")
            {
                int sum=0,cnt=0;
                for(int i=0;i<m;i++)
                     if(p[i].id.substr(1,3)==c)
                  {
                      cnt++;
                      sum+=p[i].score;
                   }
                  if(!cnt)cout<<"NA"<<endl;
                  else printf("%d %d\n",cnt,sum);
            }
            else{
                    unordered_map<string,int> hash;
                        for(int i=0;i<m;i++)
                      if(p[i].id.substr(4,6)==c)
                        hash[p[i].id.substr(1,3)]++;

                           //利用vector(pair)从hash表中取出第一个键考室号,以及第二个键该考室号的人数
                          vector<pair<int,string>> room;
                           for(auto t:hash)
                          room.push_back({-t.second,t.first}); //因为vecotr默认递增的,加符号使其变为递减,以此存入vector的第一个键(加负号即可),第二个键存入考室号

                      sort(room.begin(),room.end()); //使其递减排序
                      if(room.empty()) cout<<"NA"<<endl;
                      else
                         for(auto r:room)
                         printf("%s %d\n",r.second.c_str(),-r.first);
            }

      }

    return 0;
}




题目描述

每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜。

本题就请你实现这个功能。

输出格式

首先在一行中输出单位个数。随后按以下格式非降序输出单位的排行榜:

排名 学校 加权总分 考生人数
其中 排名 是该单位的排名(从 1 开始);学校 是全部按小写字母输出的单位码;加权总分 定义为 乙级总分/1.5 + 甲级总分 + 顶级总分*1.5 的整数部分;考生人数 是该属于单位的考生的总人数。

学校首先按加权总分排行。如有并列,则应对应相同的排名,并按考生人数升序输出。如果仍然并列,则按单位码的字典序从小到大输出。

样例

输入样例:
10
A57908 85 Au
B57908 54 LanX
A37487 60 au
T28374 67 CMU
T32486 24 hypu
A66734 92 cmu
B76378 71 AU
A47780 45 lanx
A72809 100 pku
A03274 45 hypu

输出样例:
5
1 cmu 192 2
1 au 192 3
3 pku 100 1
4 hypu 81 2
4 lanx 81 2

算法

简单模拟

C++ 代码

#include<bits/stdc++.h>
using namespace std;
struct school{
    string name;
    double score;
    int num;
};
bool cmp(school a,school b)
{
    if(a.score!=b.score) return a.score>b.score;
    else if(a.num!=b.num) return a.num<b.num;
    return a.name<b.name;
}
int main()
{
     int n;
     cin>>n;
     unordered_map<string,school> sch;

     for(int i=0;i<n;i++)
     {
         string id,sname;
         double score;
         cin>>id>>score>>sname;

         if(id[0]=='B') score/=1.5;
         else if(id[0]=='T')  score*=1.5;

         for(auto& c:sname) c=tolower(c); //对于name中的每个字符,c是一个引用,赋值语句将会改变sname中字符的值
             sch[sname].name=sname;    //将sname中的字符赋值给s[chsname]中
             sch[sname].score+=score;
             sch[sname].num++;
     }
        //利用迭代器遍历哈希表sch,并将哈希表sch中的成绩取整后,然后将sch结构体压入数组中
     vector<school> v;
      for(auto i:sch)
      {
          i.second.score=(int)(i.second.score+1e-8);//因为double的精度为8位,避免出现0.999999999的情况
          v.push_back(i.second);
      }
      sort(v.begin(),v.end(),cmp);//按照定义的cmp规则排序(成绩总分不同,成绩总分高的排前面,如果成绩总分相同,人数少的排前面)
      cout<<v.size()<<endl;
        int rank=1;
        for(int i=0;i<v.size();i++)
        {
             auto t=v[i];
             if(t.score!=v[i-1].score)rank=i+1;  //if(i && t.score!=v[i-1].score)
             printf("%d %s %d %d\n",rank,t.name.c_str(),(int)t.score,t.num);
        }
    return 0;
}






题目描述

约翰 PAT 考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔 N 个人就发出一个红包。

请你编写程序帮助他确定中奖名单。

输出格式

输入第一行给出三个正整数 M,N,S,分别是转发的总量、小明决定的中奖间隔、以及第一位中奖者的序号(编号从 1 开始)。

随后 M 行,顺序给出转发微博的网友的昵称(不超过 20 个字符、不包含空格回车的非空字符串)。

注意:可能有人转发多次,但不能中奖多次。

所以如果处于当前中奖位置的网友已经中过奖,则跳过他顺次取下一位。

样例

输入样例1:
9 3 2
Imgonnawin!
PickMe
PickMeMeMeee
LookHere
Imgonnawin!
TryAgainAgain
TryAgainAgain
Imgonnawin!
TryAgainAgain

输出样例1:
PickMe
Imgonnawin!
TryAgainAgain

输入样例2:
2 3 5
Imgonnawin!
PickMe

输出样例2:
Keep going...

算法1

利用set结构,可查找字符串值是否存在的特性,处理重复名字的情况。

C++ 代码

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
string name[N];
 int m,n,s;
int main()
{
      cin>>m>>n>>s;
      for(int i=1;i<=m;i++)
       cin>>name[i];

       int k=s;
       set<string> hash;
         while(k<=m)
        {
            if(hash.count(name[k]))k++;
            else
            {
                cout<<name[k]<<endl;
                hash.insert(name[k]);
                k+=n;
            }
        }
        if(hash.empty())puts("Keep going...");
    return 0;
}




题目描述

基本任务非常简单:给定 N 个实数,请你计算它们的平均值。

但是令事情变得复杂的是,某些输入数字可能不合法。

合法输入数字指 [−1000,1000] 范围内的精确到不超过 2 个小数位的实数。

在计算平均值时,不得将这些非法数字计算在内。

输出格式

基本任务非常简单:给定 N 个实数,请你计算它们的平均值。

但是令事情变得复杂的是,某些输入数字可能不合法。

合法输入数字指 [−1000,1000] 范围内的精确到不超过 2 个小数位的实数。

在计算平均值时,不得将这些非法数字计算在内。

样例

输入样例1:
7
5 -3.2 aaa 9999 2.3.4 7.123 2.35
输出样例1:
ERROR: aaa is not a legal number
ERROR: 9999 is not a legal number
ERROR: 2.3.4 is not a legal number
ERROR: 7.123 is not a legal number
The average of 3 numbers is 1.38
输入样例2:
2
aaa -9999
输出样例2:
ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined

算法

利用sscanf将字符串读入一个double的数据型,然后用sprintf将此浮点数保留两位小数输出到一个字符串中 判断二者是否相等即可

C++ 代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
     int n,cnt=0;cin>>n;
    char a[50],b[50];
    double temp,sum=0.0;
    for(int i=0;i<n;i++)
    {
       scanf("%s",a);
       sscanf(a,"%lf",&temp);//将读入的a中的字符串中的实数(字母除外)以浮点数的形式写到temp中(sscanf是从左到右)
       sprintf(b,"%.2f",temp);  //将temp字符串中的实数以保留俩位小数的形式输入b中(从右到左)
       int flag=0;
        for(int j=0;j<strlen(a);j++)
            if(a[j]!=b[j]) flag=1;
            if(flag || temp<-1000 ||temp>1000)
            {
            printf("ERROR;%s is not a legal number\n",a);
              continue;
            }
            else
              {
                  sum+=temp;
                  cnt++;
              }
    }
    if(cnt==1)
    {
        printf("The avarage of 1 number is %.2f",sum);
    }
    if(cnt>1)
    {
        printf("The avarage of %d number is %.2f",cnt,sum/cnt);
    }
    else
    {
        printf("The average of 0 numbers is Undefined");
    }
    return 0;
}




题目描述

不同的人对描述同一种事物的同义词的偏爱程度可能不同。

例如,在说警察时,有人喜欢用 the police,有人喜欢用 the cops。

分析说话方式有助于确定说话者的身份,这在验证诸如和你线上聊天的是否是同一个人十分有用。

现在,给定一段从某人讲话中提取的文字,你能确定他的最常用词吗?

输出格式

共一行,输出最常用词以及其出现次数。

如果常用词有多个,则输出字典序最小的那个单词。

注意,单词在输出时,必须全部小写。

单词是指由连续的字母和数字构成的,被非字母数字字符或行首/行尾分隔开的,连续序列。

单词不区分大小写。

样例

输入样例:
Can1: "Can a can can a can?  It can!"
输出样例:
can 5

算法1

双指针算法:
输出出现频率最高的单词 不区分大小写 都当成小写字母来判断
①读入一整行,getline(cin,str)
②提取字符串中的每个单词
类似双指针算法
for(i=0;i<str.size();i)//外重循环遍历整个字符串
if 如果是字母或数字,则是整个单词的第一个字母//非单词部分,可以直接忽略,考虑所有是字母部分的字符
//把整个单词找出来
j=i;
while(j<str.size() && ) 只要j在范围内并且第j个字符也是字母或数字
j

    i=j; 因为最后i要加加
循环结束后,i到j之间是完整的单词

C++ 代码

#include<bits/stdc++.h>
using namespace std;
bool check(char c)
{
    if(c>='0'&&c<='9')return true;
    if(c>='a'&& c<='z')return true;
    if(c>='A'&&c<='Z')return true;
    return false;
}
int main()
{
    string s;
    getline(cin,s);
     map<string,int> hash;

    for(int i=0;i<s.size();i++)
         if(check(s[i]))
         {
              string word;
                int j=i;
             while(j<s.size() && check(s[j]))
                word+=tolower(s[j++]);
                 hash[word]++;
                  i=j;
         }
     string res;
    int cnt=0;
    for(auto it:hash)
    if(it.second>cnt )
    {
        res=it.first;
        cnt=it.second;
    }
    cout<<res<<" "<<cnt<<endl;
    return 0;
}

算法2

  1. ⼤⼩写不区分,所以统计之前要先s[i] = tolower(s[i]);
  2. [0-9 A-Z a-z]可以简写为cctype头⽂件⾥⾯的⼀个函数isalnum~~
  3. 必须⽤getline读⼊⼀⻓串的带空格的字符串~~
  4. ⼀定要当word不为空的时候hash[word]++,因为word为空也会被统计的!!!~~
  5. 最重要的是~如果i已经到了最后⼀位,不管当前位是不是字⺟数字,都得将当前这个word放到hash
    ⾥⾯(只要word⻓度不为0)

C++ 代码

#include<bits/stdc++.h>
using namespace std;
bool check(char c)
{
    if(c>='0'&&c<='9')return true;
    if(c>='a'&& c<='z')return true;
    if(c>='A'&&c<='Z')return true;
    return false;
}
int main()
{
    string s;
    getline(cin,s);
     map<string,int> hash;
      string word;
    for(int i=0;i<s.size();i++)
    {    
         if(check(s[i]))
         {
                word+=tolower(s[i]);
         }
         if(!check(s[i]) || i==s.size()-1)
         {
             if(word.size()!=0) hash[word]++;
                word="";
         }
    }
    int cnt=0;
 for(auto it:hash)
{
    if(it.second>cnt )
    {
        word=it.first;
        cnt=it.second;
    }
}
    cout<<word<<" "<<cnt<<endl;
    return 0;
}



题目描述

给定两个字符串 S1 和 S2,S=S1−S2 定义为将 S1 中包含的所有在 S2 中出现过的字符删除后得到的字符串。

你的任务就是计算 S1−S2。

输出格式

输出共一行,表示 S1−S2 的结果。

样例

输入样例:
They are students.
aeiou

输出样例:
Thy r stdnts.

算法1

在保利枚举的基础上,查询s1中是否有s2的字符串,现将s2插入到哈希表中,利用哈希表查找的效率为O(1),然后利用迭代器遍历s1中的每个字符在哈希表中是否重复,即哈希表中的s2与s1相等的字符个数是否大于0,如果大于0既有重复,那就不加入答案字符串数组中,否则则加入答案字符串数组。

C++ 代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s1,s2,res;
    getline(cin,s1);
    getline(cin,s2);
    unordered_set<char> hash;
    for(auto b:s2)
      hash.insert(b);
      for(auto c:s1)
      {
          if(!hash.count(c))
          res+=c;
      }
      cout<<res<<endl;
      return 0;
}