算法笔记 上机训练实战指南 第6章 C++标准模板库(STL)介绍 学习笔记
6.1 vector的常见用法详解
PAT A1039 Course List for Student (25分)
Zhejiang University has 40000 students and provides 2500 courses. Now given the student name lists of all the courses, you are supposed to output the registered course list for each student who comes for a query.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive integers: N (≤), the number of students who look for their course lists, and K (≤), the total number of courses. Then the student name lists are given for the courses (numbered from 1 to K) in the following format: for each course i, first the course index i and the number of registered students Ni (≤) are given in a line. Then in the next line, Ni student names are given. A student name consists of 3 capital English letters plus a one-digit number. Finally the last line contains the N names of students who come for a query. All the names and numbers in a line are separated by a space.
Output Specification:
For each test case, print your results in N lines. Each line corresponds to one student, in the following format: first print the student's name, then the total number of registered courses of that student, and finally the indices of the courses in increasing order. The query results must be printed in the same order as input. All the data in a line must be separated by a space, with no extra space at the end of the line.
Sample Input:
11 5
4 7
BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
1 4
ANN0 BOB5 JAY9 LOR6
2 7
ANN0 BOB5 FRA8 JAY9 JOE4 KAT3 LOR6
3 1
BOB5
5 9
AMY7 ANN0 BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
ZOE1 ANN0 BOB5 JOE4 JAY9 FRA8 DON2 AMY7 KAT3 LOR6 NON9
Sample Output:
ZOE1 2 4 5
ANN0 3 1 2 5
BOB5 5 1 2 3 4 5
JOE4 1 2
JAY9 4 1 2 4 5
FRA8 3 2 4 5
DON2 2 4 5
AMY7 1 5
KAT3 3 2 4 5
LOR6 4 1 2 4 5
NON9 0
#include<cstdio> #include<algorithm> #include<vector> using namespace std; const int maxn = 26*26*26*10 + 1; vector<int> selectCourse[maxn]; int getID(char name[]){ int id = 0; for(int i=0;i<3;i++){ id = id * 26 + (name[i] - 'A'); } id = id*10 + (name[3]-'0'); return id; } int main(){ int n,k; scanf("%d%d",&n,&k); for(int i=0;i<k;i++){ int course,num; scanf("%d%d",&course,&num); for(int j=0;j<num;j++){ char name[10]; scanf("%s",name); int id = getID(name); selectCourse[id].push_back(course); } } for(int i=0;i<n;i++){ char temp[10]; scanf("%s",temp); int id1 = getID(temp); sort(selectCourse[id1].begin(),selectCourse[id1].end()); printf("%s %d",temp,selectCourse[id1].size()); for(int j = 0; j < selectCourse[id1].size(); j++){ printf(" %d",selectCourse[id1][j]); } printf("\n"); } return 0; }
PAT A1047 Student List for Course (25分)
Zhejiang University has 40,000 students and provides 2,500 courses. Now given the registered course list of each student, you are supposed to output the student name lists of all the courses.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 numbers: N (≤), the total number of students, and K (≤), the total number of courses. Then N lines follow, each contains a student's name (3 capital English letters plus a one-digit number), a positive number C (≤) which is the number of courses that this student has registered, and then followed by C course numbers. For the sake of simplicity, the courses are numbered from 1 to K.
Output Specification:
For each test case, print the student name lists of all the courses in increasing order of the course numbers. For each course, first print in one line the course number and the number of registered students, separated by a space. Then output the students' names in alphabetical order. Each name occupies a line.
Sample Input:
10 5
ZOE1 2 4 5
ANN0 3 5 2 1
BOB5 5 3 4 2 1 5
JOE4 1 2
JAY9 4 1 2 5 4
FRA8 3 4 2 5
DON2 2 4 5
AMY7 1 5
KAT3 3 5 4 2
LOR6 4 2 4 1 5
Sample Output:
1 4
ANN0
BOB5
JAY9
LOR6
2 7
ANN0
BOB5
FRA8
JAY9
JOE4
KAT3
LOR6
3 1
BOB5
4 7
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1
5 9
AMY7
ANN0
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; const int maxn = 40010; const int maxk = 2510; char name[maxn][5]; vector<int> course[maxk]; bool cmp(int a,int b){ return strcmp(name[a],name[b]) < 0; } int main(){ int n,k; scanf("%d%d",&n,&k); for(int i=0;i<n;i++){ int num; scanf("%s %d",name[i],&num); for(int j=0;j<num;j++){ int courseid; scanf("%d",&courseid); course[courseid].push_back(i); } } for(int i=1;i<=k;i++){ printf("%d %d\n",i,course[i].size()); sort(course[i].begin(),course[i].end(),cmp); for(int j=0;j<course[i].size();j++){ printf("%s\n",name[course[i][j]]); } } return 0; }
Given two sets of integers, the similarity of the sets is defined to be /, where Nc is the number of distinct common numbers shared by the two sets, and Nt is the total number of distinct numbers in the two sets. Your job is to calculate the similarity of any given pair of sets.
Input Specification:
Each input file contains one test case. Each case first gives a positive integer N (≤) which is the total number of sets. Then N lines follow, each gives a set with a positive M (≤) and followed by M integers in the range [0]. After the input of sets, a positive integer K (≤) is given, followed by K lines of queries. Each query gives a pair of set numbers (the sets are numbered from 1 to N). All the numbers in a line are separated by a space.
Output Specification:
For each query, print in one line the similarity of the sets, in the percentage form accurate up to 1 decimal place.
Sample Input:
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
Sample Output:
50.0%
33.3%
#include<cstdio> #include<set> using namespace std; const int maxn = 55; set<int> st[maxn]; void compare(int a,int b){ int totalnum=st[b].size(),samenum=0; for(set<int>::iterator it=st[a].begin(); it != st[a].end();it++){ if(st[b].find(*it) != st[b].end()) samenum++; else totalnum++; } printf("%.1f%%\n",samenum * 100.0 / totalnum); } int main(){ int n,m; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&m); for(int j=0;j<m;j++){ int temp; scanf("%d",&temp); st[i].insert(temp); } } int query; scanf("%d",&query); int q1,q2; for(int i=0;i<query;i++){ scanf("%d%d",&q1,&q2); compare(q1,q2); } return 0; }
If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0 with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.
Input Specification:
Each input file contains one test case which gives three numbers N, A and B, where N (<) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than 1, and that its total digit number is less than 100.
Output Specification:
For each test case, print in a line YES
if the two numbers are treated equal, and then the number in the standard form 0.d[1]...d[N]*10^k
(d[1]
>0 unless the number is 0); or NO
if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.
Note: Simple chopping is assumed without rounding.
Sample Input 1:
3 12300 12358.9
Sample Output 1:
YES 0.123*10^5
Sample Input 2:
3 120 128
Sample Output 2:
NO 0.120*10^3 0.128*10^3
#include<iostream> #include<string> using namespace std; int n; string deal(string s,int &e){ int k = 0; while(s.length() > 0 && s[0] == '0'){ s.erase(s.begin()); } if(s[0] == '.'){ s.erase(s.begin()); while(s.length()>0 && s[0]=='0'){ s.erase(s.begin()); e--; } }else{ while(k < s.length() && s[k]!='.'){ k++; e++; } if(k < s.length()){ s.erase(s.begin()+k); } } if(s.length() == 0){ e = 0; } int num = 0; k = 0; string res; while(num < n){ if(k < s.length()) res += s[k++]; else res += '0'; num++; } return res; } int main(){ string s1,s2,s3,s4; cin>>n>>s1>>s2; int e1 = 0,e2 = 0; s3 = deal(s1,e1); s4 = deal(s2,e2); if(s3 == s4 && e1 == e2){ cout<<"YES 0."<<s3<<"*10^"<<e1<<endl; }else{ cout<<"NO 0."<<s3<<"*10^"<<e1<<" 0."<<s4<<"*10^"<<e2<<endl; } return 0; }
PAT 1044 火星数字 (20分)
火星人是以 13 进制计数的:
- 地球人的 0 被火星人称为 tret。
- 地球人数字 1 到 12 的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。
- 火星人将进位以后的 12 个高位数字分别称为:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。
例如地球人的数字 29
翻译成火星文就是 hel mar
;而火星文 elo nov
对应地球数字 115
。为了方便交流,请你编写程序实现地球和火星数字之间的互译。
输入格式:
输入第一行给出一个正整数 N(<),随后 N 行,每行给出一个 [0, 169) 区间内的数字 —— 或者是地球文,或者是火星文。
输出格式:
对应输入的每一行,在一行中输出翻译后的另一种语言的数字。
输入样例:
4
29
5
elo nov
tam
输出样例:
hel mar
may
115
13
#include<cstdio> #include<iostream> #include<map> #include<string> using namespace std; string digitnum[13]={"tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec"}; string tennum[13]={"tret","tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou"}; string numToStr[170]; map<string,int> strToNum; void init(){ for(int i=0;i<13;i++){ numToStr[i]=digitnum[i]; strToNum[digitnum[i]] = i; numToStr[13*i] = tennum[i]; strToNum[tennum[i]] = 13*i; } for(int i=1;i<13;i++){ for(int j=1;j<13;j++){ string str = tennum[i] + " " + digitnum[j]; numToStr[i*13 + j] = str; strToNum[str] = i*13+j; } } } int main(){ int n; scanf("%d",&n); getchar(); init(); for(int i=0;i<n;i++){ string str; getline(cin,str); if(str[0]>='0' && str[0]<='9'){ int num = 0; for(int j=0;j<str.length();j++){ num = num*10 + (str[j]-'0'); } cout<<numToStr[num]<<endl; } else{ cout<<strToNum[str]<<endl; } } return 0; }
PAT A1054 The Dominant Color (20分)
Behind the scenes in the computer's memory, color is always talked about as a series of 24 bits of information for each pixel. In an image, the color with the largest proportional area is called the dominant color. A strictly dominant color takes more than half of the total area. Now given an image of resolution M by N (for example, 8), you are supposed to point out the strictly dominant color.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive numbers: M (≤) and N (≤) which are the resolutions of the image. Then N lines follow, each contains M digital colors in the range [0). It is guaranteed that the strictly dominant color exists for each input image. All the numbers in a line are separated by a space.
Output Specification:
For each test case, simply print the dominant color in a line.
Sample Input:
5 3
0 0 255 16777215 24
24 24 0 0 24
24 0 24 24 24
Sample Output:
24
#include<cstdio> #include<map> using namespace std; map<int,int> count; int main(){ int m,n,temp; scanf("%d%d",&m,&n); for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ scanf("%d",&temp); if(count.find(temp)!=count.end()) count[temp]++; else count[temp] = 1; } } int k=0,MAX = 0; for(map<int,int>::iterator it=count.begin();it != count.end();it++){ if(it->second > MAX){ k = it->first; MAX = it->second; } } printf("%d\n",k); return 0; }
PAT A1071 Speech Patterns (25分)
People often have a preference among synonyms of the same word. For example, some may prefer "the police", while others may prefer "the cops". Analyzing such patterns can help to narrow down a speaker's identity, which is useful when validating, for example, whether it's still the same person behind an online avatar.
Now given a paragraph of text sampled from someone's speech, can you find the person's most commonly used word?
Input Specification:
Each input file contains one test case. For each case, there is one line of text no more than 1048576 characters in length, terminated by a carriage return \n
. The input contains at least one alphanumerical character, i.e., one character from the set [0-9 A-Z a-z
].
Output Specification:
For each test case, print in one line the most commonly occurring word in the input text, followed by a space and the number of times it has occurred in the input. If there are more than one such words, print the lexicographically smallest one. The word should be printed in all lower case. Here a "word" is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end.
Note that words are case insensitive.
Sample Input:
Can1: "Can a can can a can? It can!"
Sample Output:
can 5
#include<cstdio> #include<map> #include<string> #include<iostream> using namespace std; map<string,int> count; bool check(char c){ if(c>='a' && c<='z') return true; if(c>='A' && c<='Z') return true; if(c>='0' && c<='9') return true; return false; } int main(){ string str; getline(cin,str); int i=0; while(i < str.length()){ string word=""; while(check(str[i]) == true){ if(str[i]>='A' && str[i]<='Z'){ str[i] += 32; } word += str[i]; i++; } if(count.find(word)!=count.end()) count[word]++; else count[word]=1; while(i<str.length() && check(str[i]) == false){ i++; } } string a; int MAX=0; for(map<string,int>::iterator it=count.begin();it!=count.end();it++){ if(it->second > MAX){ MAX = it->second; a = it->first; } } cout<<a<<" "<<MAX<<endl; return 0; }
A Digital Library contains millions of books, stored according to their titles, authors, key words of their abstracts, publishers, and published years. Each book is assigned an unique 7-digit number as its ID. Given any query from a reader, you are supposed to output the resulting books, sorted in increasing order of their ID's.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤) which is the total number of books. Then N blocks follow, each contains the information of a book in 6 lines:
- Line #1: the 7-digit ID number;
- Line #2: the book title -- a string of no more than 80 characters;
- Line #3: the author -- a string of no more than 80 characters;
- Line #4: the key words -- each word is a string of no more than 10 characters without any white space, and the keywords are separated by exactly one space;
- Line #5: the publisher -- a string of no more than 80 characters;
- Line #6: the published year -- a 4-digit number which is in the range [1000, 3000].
It is assumed that each book belongs to one author only, and contains no more than 5 key words; there are no more than 1000 distinct key words in total; and there are no more than 1000 distinct publishers.
After the book information, there is a line containing a positive integer M (≤) which is the number of user's search queries. Then M lines follow, each in one of the formats shown below:
- 1: a book title
- 2: name of an author
- 3: a key word
- 4: name of a publisher
- 5: a 4-digit number representing the year
Output Specification:
For each query, first print the original query in a line, then output the resulting book ID's in increasing order, each occupying a line. If no book is found, print Not Found
instead.
Sample Input:
3
1111111
The Testing Book
Yue Chen
test code debug sort keywords
ZUCS Print
2011
3333333
Another Testing Book
Yue Chen
test code sort keywords
ZUCS Print2
2012
2222222
The Testing Book
CYLL
keywords debug book
ZUCS Print2
2011
6
1: The Testing Book
2: Yue Chen
3: keywords
4: ZUCS Print
5: 2011
3: blablabla
Sample Output:
1: The Testing Book
1111111
2222222
2: Yue Chen
1111111
3333333
3: keywords
1111111
2222222
3333333
4: ZUCS Print
1111111
5: 2011
1111111
2222222
3: blablabla
Not Found
#include<iostream> #include<cstdio> #include<map> #include<set> #include<string> using namespace std; map<string,set<int> > mptitle,mpauthor,mpkey,mppub,mpyear; void query(map<string,set<int> > &mp,string &str){ if(mp.find(str) == mp.end()) printf("Not Found\n"); else{ for(set<int>::iterator it=mp[str].begin(); it != mp[str].end();it++){ printf("%07d\n",*it); } } } int main(){ int n,id; string title,author,key,pub,year; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&id); char c = getchar(); getline(cin,title); mptitle[title].insert(id); getline(cin,author); mpauthor[author].insert(id); while(cin>>key){ mpkey[key].insert(id); c = getchar(); if(c=='\n') break; } getline(cin,pub); mppub[pub].insert(id); getline(cin,year); mpyear[year].insert(id); } int m; scanf("%d",&m); for(int i=0;i<m;i++){ int temp; scanf("%d: ",&temp); string tempstr; getline(cin,tempstr); cout<<temp<<": "<<tempstr<<endl; if(temp==1){ query(mptitle,tempstr); }else if(temp==2){ query(mpauthor,tempstr); }else if(temp==3){ query(mpkey,tempstr); }else if(temp==4){ query(mppub,tempstr); }else{ query(mpyear,tempstr); } } return 0; }