目录
1124 Raffle for Weibo Followers
1141 PAT Ranking of Institutions
1153 Decode Registration Card of PAT
思维能力:
快速想出解题思路,用什么数据结构存,用什么枚举方式求出来
代码熟练度:
快速写出代码并调试通过
1001 A+B Format
注意点
注意拼接顺序,是num[i] + res 还是 res + num[i]
#include<iostream>
using namespace std;
int main(){
int a,b;
cin >> a >> b; //存a和b
int c = a+b;
string num = to_string(c);
string res;
for (int i = num.size() - 1, j = 0 ; i >= 0; i--)
{
res = num[i] + res; //从最后一位开始拼接
++ j;
if(j % 3 == 0 && i && num[i-1] != '-') res = ',' + res; //每3位填一个‘,’
}
cout << res;
return 0;
}
1005 Spell It Right
注意点
1.二维char数组的用法
2.行末空格的处理手法
#include<iostream>
using namespace std;
int main() {
string n;
cin >> n;
int sum = 0;
for(auto c : n) sum += c - '0'; // -'0' 把字符‘1’转成数字 1
string str = to_string(sum);
char word[10][10] = {
"zero","one","two","three","four",
"five","six","seven","eight","nine",
};
cout << word[str[0] - '0']; //先输出第一个
for (int i = 1; i < str.size(); i++){
cout << " " << word[str[i] - '0']; //每个先输出空格 再输出字符 这样最后一位不会多一个空格
}
return 0;
}
1006 Sign In and Sign Out
注意点
HH:MM:SS 看成字符串
#include<iostream>
using namespace std;
int main(){
string open_id,open_time;
string close_id,close_time;
int m;
cin >> m;
for (int i = 0; i < m; i++){
string id,in_time,out_time;
cin >> id >> in_time >> out_time;
if(!i || in_time < open_time){ //i=0 第一个时 直接赋值 HH:MM:SS位数相同,都是两位两位比,先比较H再比较M,按字典序比
open_id = id; //默认string的比较就是按字典序比的
open_time = in_time;
}
if(!i || out_time > close_time){
close_id = id;
close_time = out_time;
}
}
cout << open_id << " " << close_id << endl;
return 0;
}
1035 Password
单词:
lowercase 小写
uppercase 大写
#include<iostream>
using namespace std;
const int N = 1010;
string name[N],pwd[N];
string change(string str){ //修改密码
string res;
for(auto c : str){
if(c == '1') res += '@';
else if (c == '0') res += '%';
else if (c == 'l') res += 'L';
else if (c == 'O') res += 'o';
else res += c;
}
return res;
}
int main(){
int n;
cin >> n;
int m = 0;
for (int i = 0; i < n; i++){
string cur_name, cur_pwd;
cin >> cur_name >> cur_pwd;
string changed_pwd = change(cur_pwd);
if(changed_pwd != cur_pwd){
name[m] = cur_name;
pwd[m] = changed_pwd;
m++;
}
}
if(!m){
if(n == 1) {
printf("There is 1 account and no account is modified");
}else {
printf("There are %d accounts and no account is modified", n);
}
}else{
cout << m << endl;
for (int i = 0; i < m; i++){
cout << name[i] << " " << pwd[i] << endl;
}
}
return 0;
}
1036 Boys vs Girls
#include<iostream>
using namespace std;
int main(){
int n;
string girl_name,girl_id; //女生第一名的信息
int girl_score;
string boy_name,boy_id; //男生第一名的信息
int boy_score;
cin >> n;
for (int i = 0; i < n; i++){
string name,sex,id;
int score;
cin >> name >> sex >> id >> score;
if(sex == "F"){ //如果当前同学是女生
if(girl_name.empty() || girl_score < score){
girl_name = name;
girl_id = id;
girl_score = score;
}
}else{ //当前同学是男生
if(boy_name.empty() || boy_score > score){
boy_name = name;
boy_id = id;
boy_score = score;
}
}
}
if(girl_name.empty()) puts("Absent");
else cout << girl_name << ' ' << girl_id << endl;
if(boy_name.empty()) puts("Absent");
else cout << boy_name << ' ' << boy_id << endl;
if(girl_name.size() && boy_name.size()){
cout << abs(girl_score - boy_score);
}else{
cout << "NA" << endl;
}
return 0;
}
1050 String Subtraction
解法1: 暴力解
#include<iostream>
using namespace std;
string s1,s2;
//暴力
bool check_exists(char c){
for(auto a : s2){
if(a == c){
return true;
}
}
return false;
}
int main(){
getline(cin , s1); //读入带空格的字符串
getline(cin , s2);
string res;
for(auto c : s1){
if(!check_exists(c)){
res += c;
}
}
cout << res << endl;
return 0;
}
解法2: 快速解(hashset)
注意点
读入带有空格的string 用getline
#include<iostream>
#include<unordered_set>
using namespace std;
string s1, s2;
//优化 用哈希表
int main(){
getline(cin , s1);
getline(cin , s2);
unordered_set<char> set; //定义hash
//不允许有重复的元素,出现过就是1,没出现过就是0
for(auto c : s2) set.insert(c); //将s2中的字符插入hash表
string res;
for(auto c : s1){
if(!set.count(c)){
res += c;
}
}
cout << res << endl;
return 0;
}
1071 Speech Patterns
单词:
synonyms 同义
validating 验证
解析
1.getline读入一整行
2.提取每一个单词,双指针写法,再存到哈希表里统计个数
3.遍历整个哈希表,找到出现次数最多的单词
注意点
除数字和字母,其他都不算单词。
tolower() 转换为小写字母
#include<iostream>
#include<unordered_map>
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;
}
char to_lower(char c){ //大写转小写,已经是小写则不变
if(c >= 'A' && c <= 'Z') return c + 32;
return c;
}
int main(){
string str;
getline(cin, str);
unordered_map<string, int> hashmap;
for(int i = 0; i < str.size(); i++)
if(check(str[i])){
string word;
int j = i;
while(j < str.size() && check(str[j])) word += to_lower(str[j++]); //也可直接用tolower函数
hashmap[word]++;
i = j;
}
string word;
int cnt = -1;
for(auto item : hashmap)
if(item.second > cnt || item.second == cnt && item.first < word){
word = item.first;
cnt = item.second;
}
cout << word << ' ' << cnt << endl;
return 0;
}
1061 Dating
单词:
case sensitive 区分大小写
capital letter 大写字母
注意点
1、一对字符相同,是指在两个字符相同且在字符串的位置也相同。
2、前两个字符串中第一对相同的大写英文字母,是指第一对能够正确代表日期的大写英文字母。
3、前两个字符串中第二对相同的字符,是指位于代表日期的字符后面的,第一对相同的,能够正确代表小时的字符。
不足两位要补0。
#include <cstdio>
#include <iostream>
using namespace std;
int main(){
string a, b, c, d;
cin >> a >> b >> c >> d;
int k = 0;
while (true){ //题目说了一定有结果
if (a[k] == b[k] && a[k] >= 'A' && a[k] <= 'G') break;
k ++ ;
}
char weekdays[7][4] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
printf("%s ", weekdays[a[k] - 'A']);
k ++ ; //k往后走一个,继续往后找第二个满足要求的字母
while (true){
if (a[k] == b[k] && ((a[k] >= '0' && a[k] <= '9' ) || (a[k] >= 'A' && a[k] <= 'N'))) break;
k ++ ;
}
printf("%02d:", a[k] <= '9' ? a[k] - '0' : a[k] - 'A' + 10);
for (int i = 0;; i ++ )
if (c[i] == d[i] && ((c[i] >= 'a' && c[i] <= 'z') || (c[i] >= 'A' && c[i] <= 'Z'))){
printf("%02d\n", i);
break;
}
return 0;
}
1016 Phone Bills
注意点
1美元 = 100美分
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
const int N = 1010, M = 31 * 1440 + 10;
int n;
int cost[24]; // 每个时间段的话费
double sum[M]; // 从当月1号00:00开始到每个时刻所花费的钱数
struct Record{
int minutes; //时间
string state; //状态
string format_time; //格式化时间
bool operator< (const Record& t) const{
return minutes < t.minutes;
}
};
map<string, vector<Record>> persons;
int main(){
for (int i = 0; i < 24; i ++ ) cin >> cost[i];
for (int i = 1; i < M; i ++ ) sum[i] = sum[i - 1] + cost[(i - 1) % 1440 / 60] / 100.0;
cin >> n;
char name[25], state[10], format_time[20];
int month, day, hour, minute;
for (int i = 0; i < n; i ++ ){
scanf("%s %d:%d:%d:%d %s", name, &month, &day, &hour, &minute, state);
sprintf(format_time, "%02d:%02d:%02d", day, hour, minute);
int minutes = (day - 1) * 1440 + hour * 60 + minute;
persons[name].push_back({minutes, state, format_time});
}
for (auto &person : persons){
auto name = person.first;
auto records = person.second;
sort(records.begin(), records.end());
double total = 0;
for (int i = 0; i + 1 < records.size(); i ++ ){
auto a = records[i], b = records[i + 1];
if (a.state == "on-line" && b.state == "off-line"){
if (!total) printf("%s %02d\n", name.c_str(), month);
cout << a.format_time << ' ' << b.format_time;
double c = sum[b.minutes] - sum[a.minutes];
printf(" %d $%.2lf\n", b.minutes - a.minutes, c);
total += c;
}
}
if (total) printf("Total amount: $%.2lf\n", total);
}
return 0;
}
1060 Are They Equal
解析
1. 转成浮点数
2.对比转换后 是否相同
注意点
- 数字不一定标准,可能有前导 00。(一般有个点不过就是这个问题)
- 如果数值是0,则指数规定为0。
此题用了很多string函数
find( ) 找到小数点的位置,从0开始计数, -1代表没有这个字符
#include <iostream>
#include <cstring>
using namespace std;
string change(string a, int n){
int k = a.find(".");// 找到小数点的位置,从0开始计数
if (k == -1){ // 如果字符串中没有 ".",在末尾给它加上一位 "." ,k=-1就是没有
a += '.';
k = a.find(".");
}
string s = a.substr(0, k) + a.substr(k + 1); // 去除 ".",做成一个新的字符串s
while (s.size() && s[0] == '0'){// 去除前导0
s = s.substr(1); //如果数值是0则字符串会变为空
k--;
}
if (s.empty()) k = 0; // 如果字符串为空 代表s="0",特殊处理一下
if (s.size() > n) s = s.substr(0, n); // 字符串长度比要求保留的位数要多, 则进行截取操作
else s += string(n - s.size(), '0'); // 否则 在末尾补0
return "0." + s + "*10^" + to_string(k);
}
int main(){
int n;
string a, b;
cin >> n >> a >> b;
a = change(a, n);
b = change(b, n);
if (a == b) cout << "YES " << a << endl;
else cout << "NO " << a << ' ' << b << endl;
return 0;
}
1073 Scientific Notation
解析
从E分割出尾数和阶码
注意点
#include <iostream>
using namespace std;
int main(){
string s;
cin >> s;
if (s[0] == '-') cout << '-';
int k = s.find("E");
string a = s[1] + s.substr(3, k - 3); // +1.23400E-03 中 取出 123400
int b = stoi(s.substr(k + 1)); //取出阶码
b ++ ; //小数点向左移动一位,缩小十倍,b++
if (b <= 0) a = "0." + string(-b, '0') + a; // +1.23400E-03 -> 0.00 123400
else if (b >= a.size()) a += string(b - a.size(), '0'); // -1.2E+10 -> -12 000 000 000
else a = a.substr(0, b) + '.' + a.substr(b); // +1.234E2 -> 123.4
cout << a << endl;
return 0;
}
1077 Kuchiguse
单词:
suffix 后缀
注意点
#include <iostream>
using namespace std;
const int N = 110;
int n;
string s[N];
int main(){
cin >> n;
// 把回车读取, 再读取每一行
getchar();
for (int i = 0; i < n; i ++) getline(cin, s[i]);
// 后缀长度为 1
// 后缀长度为 2
// ... 直到sf.size() == s[0].size() 暴力枚举每一种可能的公共后缀
for (int k = s[0].size(); k > 0; k --){
string sf = s[0].substr(s[0].size() - k); //后缀
bool is_matched = true;
for (int i = 1; i < n; i ++ ) //枚举剩下字符串
if (k > s[i].size() || s[i].substr(s[i].size() - k) != sf){
is_matched = false;
break;
}
if (is_matched){
cout << sf << endl;
return 0;
}
}
puts("nai");
return 0;
}
1082 Read Number in Chinese
解析
将单位和数字分开处理
1. 将数字的单位按每4位数来划分:[个十百千] + 万/亿
2. 如果当前数字 > 0 且上一位数字为 0 则输出ling(仅考虑组内0的个数)
3. 如果[个十百千]中全为0,万位不用输出 100000000 yi Yi
注意点
#include <iostream>
#include <string>
using namespace std;
string Dict[] = { "Ge", "Shi", "Bai", "Qian", "Wan", "Yi" };
string Num[] = { "ling","yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };
string converNum(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; //计算每4位数中0个数量,如果有4个0则不用输出万
bool zero = false; //修改的地方,只考虑组内是否出现0
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 += Dict[j] + ' ';
}
else { //如果当前数字为0
zeroCnt++;
zero = true;
}
len--;
}
//位数大于4位,且该段不全为0,输出亿或者万
if (len / 4 > 0 && zeroCnt != 4) ans += Dict[3 + len / 4] + ' ';
}
ans.pop_back();
return ans;
}
int main() {
string str;
getline(cin, str);
str = converNum(str);
cout << str << endl;
return 0;
}
1084 Broken Keyboard
单词:
case insensitive 不区分大小写
解析
双指针
注意点
#include<iostream>
using namespace std;
int main()
{
string a,b;
cin >> a >> b;
bool st[200] = {0}; //ASCII 0-127 标记字母有没有输出过
b += '#'; //防止第二行提前扫描完,出现越界,在第二行末尾加一个没出现过的字符
for(int i = 0, j = 0; i < a.size(); i++){
char x = toupper(a[i]), y = toupper(b[j]);
if(x == y) j++;
else{
if(!st[x]) cout << x, st[x] = true;
}
}
return 0;
}
1108 Finding Average
单词:
accurate up to no more than 2 decimal places 精确到不超过小数点后2位
注意点
try catch....
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int cnt = 0; // 合法数字个数
double sum = 0; // 合法数字总和
while (n -- ){
string num;
cin >> num;
double x;
/*
不加try catch报错terminate called after throwing an instance of 'std::invalid_argument'
what(): stof(若传入不可转化为浮点型的字符串)会抛出异常
*/
bool success = true;
try{
size_t idx; // size type 用来记录大小的数据类型
x = stof(num, &idx); // 字符串转换为float型
// stof判断"5.2abc"这类字符串时视"5.2"为合法,"abc"不合法,但实际上5.2abc不合法
if (idx < num.size()) success = false; // 经stof处理后变短的字符串不合法
}
catch(...){ // 捕捉所有类型的异常
success = false; // 所有不合法的输入数字都设为error
}
if (x < -1000 || x > 1000) success = false;
int k = num.find('.');
if (k != -1 && num.size() - k > 3) success = false; // 不超过2个小数位(最后一位是num.size()-1)
if (success) cnt ++, sum += x;
else printf("ERROR: %s is not a legal number\n", num.c_str());
}
if (cnt > 1) printf("The average of %d numbers is %.2lf\n", cnt, sum / cnt);
else if (cnt == 1) printf("The average of 1 number is %.2lf\n", sum);
else puts("The average of 0 numbers is Undefined");
return 0;
}
1124 Raffle for Weibo Followers
#include <iostream>
#include <cstring>
#include <unordered_set>
using namespace std;
const int N = 1010;
int m, n, s;
string name[N];
int main(){
cin >> m >> n >> s;
for (int i = 1; i <= m; i ++ ) cin >> name[i];
unordered_set<string> hash; //记录发奖人的名字
int k = s;
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;
}
1141 PAT Ranking of Institutions
#include <iostream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;
struct School{
string name;
int cnt;
double sum;
School(): cnt(0), sum(0) {} //默认构造函数,哈希表里若某个结构体不存在,创造结构体时会调用默认构造函数
//
bool operator< (const School &t) const{
if (sum != t.sum) return sum > t.sum;
if (cnt != t.cnt) return cnt < t.cnt;
return name < t.name;
}
};
int main(){
int n;
cin >> n;
unordered_map<string, School> hash;
while (n -- ){
string id, sch;
double grade;
cin >> id >> grade >> sch;
for (auto& c : sch) c = tolower(c);
if (id[0] == 'B') grade /= 1.5;
else if (id[0] == 'T') grade *= 1.5;
hash[sch].sum += grade;
hash[sch].cnt ++ ;
hash[sch].name = sch;
}
vector<School> schools;
for (auto item : hash){
item.second.sum = (int)(item.second.sum + 1e-8);
schools.push_back(item.second);
}
sort(schools.begin(), schools.end());
cout << schools.size() << endl;
int rank = 1;
for (int i = 0; i < schools.size(); i ++ ){
auto s = schools[i];
if (i && s.sum != schools[i - 1].sum) rank = i + 1;
printf("%d %s %d %d\n", rank, s.name.c_str(), (int)s.sum, s.cnt);
}
return 0;
}
1153 Decode Registration Card of PAT
#include <iostream>
#include <cstring>
#include <unordered_map>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 10010;
int n, m;
struct Person{
string id;
int grade;
bool operator< (const Person &t) const
{
if (grade != t.grade) return grade > t.grade;
return id < t.id;
}
}p[N];
int main(){
cin >> n >> m;
for (int i = 0; i < n; i ++ ) cin >> p[i].id >> p[i].grade;
for (int k = 1; k <= m; 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> persons;
for (int i = 0; i < n; i ++ )
if (p[i].id[0] == c[0])
persons.push_back(p[i]);
sort(persons.begin(), persons.end());
if (persons.empty()) puts("NA");
else
for (auto person : persons) printf("%s %d\n", person.id.c_str(), person.grade);
}
else if (t == "2"){
int cnt = 0, sum = 0;
for (int i = 0; i < n; i ++ )
if (p[i].id.substr(1, 3) == c){
cnt ++ ;
sum += p[i].grade;
}
if (!cnt) puts("NA");
else printf("%d %d\n", cnt, sum);
}
else{
unordered_map<string, int> hash;
for (int i = 0; i < n; i ++ )
if (p[i].id.substr(4, 6) == c)
hash[p[i].id.substr(1, 3)] ++ ;
vector<pair<int, string>> rooms;
for (auto item : hash) rooms.push_back({-item.second, item.first});
sort(rooms.begin(), rooms.end());
if (rooms.empty()) puts("NA");
else
for (auto room : rooms)
printf("%s %d\n", room.second.c_str(), -room.first);
}
}
return 0;
}