生活随笔
收集整理的這篇文章主要介紹了
PAT甲级题目翻译+答案 AcWing(排序)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1012 The Best Rank (25 分)
題意 :給ID和3門成績,計算其平均分A,輸出每位學生最好的排名,A>C>M>E 思路 :如果將所需的若干個元素中使第一個元素為后幾個的平均值;容器內二分找值;題目所給ACME決定了搜索順序,因此決定了容器順序;二分時,如果是倒序的,就應該找最前面的,這里我們為了省事不寫cmp說明是從小到大的,那么我們要找的就是最后一個,最后一個等于x的數的位置,然后如果說r是a.size() - 1,說明排名是第一,那么返回1,也就是說返回值是a.size() - r 語法 :round函數四舍五入,頭文件是cmath;map的count用來找是否存在這個左值;int t[4]= {0];數組內統一初始值
# include <iostream>
# include <vector>
# include <unordered_map>
# include <algorithm>
# include <cmath> using namespace std
; unordered_map
< string
, vector
< int >> grades
;
vector
< int > q
[ 4 ] ; int get_grade ( vector
< int > & a
, int x
)
{ int l
= 0 , r
= a
. size ( ) - 1 ; while ( l
< r
) { int mid
= ( l
+ r
+ 1 ) >> 1 ; if ( a
[ mid
] <= x
) l
= mid
; else r
= mid
- 1 ; } return a
. size ( ) - r
;
} int main ( )
{ int n
, m
; cin
>> n
>> m
; for ( int i
= 0 ; i
< n
; i
++ ) { string id
; cin
>> id
; int t
[ 4 ] = { 0 } ; for ( int j
= 1 ; j
< 4 ; j
++ ) { cin
>> t
[ j
] ; t
[ 0 ] += t
[ j
] ; } t
[ 0 ] = round ( t
[ 0 ] / 3.0 ) ; for ( int j
= 0 ; j
< 4 ; j
++ ) { grades
[ id
] . push_back ( t
[ j
] ) ; q
[ j
] . push_back ( t
[ j
] ) ; } } for ( int i
= 0 ; i
< 4 ; i
++ ) sort ( q
[ i
] . begin ( ) , q
[ i
] . end ( ) ) ; char names
[ ] = "ACME" ; while ( m
-- ) { string id
; cin
>> id
; if ( grades
. count ( id
) == 0 ) puts ( "N/A" ) ; else { int res
= n
+ 1 ; char c
; for ( int i
= 0 ; i
< 4 ; i
++ ) { int rank
= get_grade ( q
[ i
] , grades
[ id
] [ i
] ) ; if ( res
> rank
) { res
= rank
; c
= names
[ i
] ; } } cout
<< res
<< ' ' << c
<< endl
; } }
}
1022 Digital Library (30 分)
語法 :
要用getline,轉戰cin auto 后面不加& 會超時 :Book結構體里的內容很多,不用引用的話,每次會將整個結構體復制一遍,效率較低。 查詢出版年限。注意,這個年限可能包含前導 0。因此,我們用字符串存 使用getline前要檢查是否需要getchar,cin前則不用 getline會把換行符也吃掉,因此一個getline前如果還是getline就不需要getchar;一個getline前如果是cin,則必須getchar stringstream ssin(line); string keyword; while (ssin >> keyword) keywords.insert(keyword); 注意容器定義的位置在循環內還是外,不像例如string類型可以重新被定義
# include <iostream>
# include <vector>
# include <algorithm>
# include <unordered_set>
# include <sstream>
using namespace std
; # define pb push_back struct Book
{ string id
, name
, author
; unordered_set
< string
> keywords
; string publisher
, year
;
} ; int main ( )
{ int n
; cin
>> n
; vector
< Book
> books
; string id
, name
, author
, keyword
, publisher
, year
; while ( n
-- ) { unordered_set
< string
> keywords
; cin
>> id
; getchar ( ) ; getline ( cin
, name
) , getline ( cin
, author
) ; string line
; getline ( cin
, line
) ; stringstream
ssin ( line
) ; while ( ssin
>> keyword
) keywords
. insert ( keyword
) ; getline ( cin
, publisher
) , getline ( cin
, year
) ; books
. push_back ( { id
, name
, author
, keywords
, publisher
, year
} ) ; } int m
; cin
>> m
; getchar ( ) ; string query
; while ( m
-- ) { getline ( cin
, query
) ; cout
<< query
<< endl
; char t
= query
[ 0 ] ; string info
= query
. substr ( 3 ) ; vector
< string
> res
; if ( t
== '1' ) { for ( auto & book
: books
) if ( book
. name
== info
) res
. pb ( book
. id
) ; } else if ( t
== '2' ) { for ( auto & book
: books
) if ( book
. author
== info
) res
. pb ( book
. id
) ; } else if ( t
== '3' ) { for ( auto & book
: books
) if ( book
. keywords
. count ( info
) ) res
. pb ( { book
. id
} ) ; } else if ( t
== '4' ) { for ( auto & book
: books
) if ( book
. publisher
== info
) res
. pb ( book
. id
) ; } else { for ( auto & book
: books
) if ( book
. year
== info
) res
. pb ( book
. id
) ; } if ( res
. empty ( ) ) puts ( "Not Found" ) ; else { sort ( res
. begin ( ) , res
. end ( ) ) ; for ( auto & id
: res
) cout
<< id
<< endl
; } }
}
1025 PAT Ranking (25 分)
題意 :
給n個考場排行表,排行表中包含準考證以及成績 求輸出總的排行表,包含 準考證,總排名(含并列),考場號,原考場中排名,
思路 :
13位準考證號 用 字符串 存 先按照各個考場內存每個學生信息,排好序后得到了原考場中的排名,再放入總的學生信息容器中 再對總容器排序,得到總排名 在排名時,按照從大到小(重載)的順序,如果是最大的或者與上一個不相等(即不并列),直接排名等于i+1,否則,等于上一個的排名 重載時注意,先按成績降序,然后是準考證升序
語法 :
auto& g = grades[i]; 結構體賦值的{}方法可以不對結構體所有信息存儲,是按順序的,比如一共有5個信息,我們可以只存前三個
# include <iostream>
# include <algorithm>
# include <vector>
using namespace std
; # define pb push_back const int N
= 110 ; struct Student
{ string id
; int grade
; int location_number
, local_rank
, final_rank
; bool operator < ( const Student
& t
) const { if ( grade
!= t
. grade
) return grade
> t
. grade
; return id
< t
. id
; }
} ; vector
< Student
> grades
[ N
] ;
vector
< Student
> all
; int main ( )
{ int n
; cin
>> n
; for ( int i
= 1 ; i
<= n
; i
++ ) { int k
; cin
>> k
; for ( int j
= 0 ; j
< k
; j
++ ) { string id
; int grade
; cin
>> id
>> grade
; grades
[ i
] . pb ( { id
, grade
, i
} ) ; } auto & g
= grades
[ i
] ; sort ( g
. begin ( ) , g
. end ( ) ) ; for ( int j
= 0 ; j
< g
. size ( ) ; j
++ ) { if ( ! j
|| g
[ j
] . grade
!= g
[ j
- 1 ] . grade
) g
[ j
] . local_rank
= j
+ 1 ; else g
[ j
] . local_rank
= g
[ j
- 1 ] . local_rank
; all
. pb ( g
[ j
] ) ; } } sort ( all
. begin ( ) , all
. end ( ) ) ; for ( int i
= 0 ; i
< all
. size ( ) ; i
++ ) { if ( ! i
|| all
[ i
] . grade
!= all
[ i
- 1 ] . grade
) all
[ i
] . final_rank
= i
+ 1 ; else all
[ i
] . final_rank
= all
[ i
- 1 ] . final_rank
; } cout
<< all
. size ( ) << endl
; for ( auto & x
: all
) cout
<< x
. id
<< ' ' << x
. final_rank
<< ' ' << x
. location_number
<< ' ' << x
. local_rank
<< endl
;
}
1028 List Sorting (25 分)
題意 :
給所有學生的id,名字,成績,要求你按照其中一個排序并輸出排行榜
# include <iostream>
# include <algorithm>
using namespace std
; const int N
= 1e5 + 10 ; struct Row
{ string id
, name
; int grade
;
} rows
[ N
] ; bool cmp1 ( Row a
, Row b
)
{ return a
. id
< b
. id
;
} bool cmp2 ( Row a
, Row b
)
{ if ( a
. name
!= b
. name
) return a
. name
< b
. name
; return a
. id
< b
. id
;
} bool cmp3 ( Row a
, Row b
)
{ if ( a
. grade
!= b
. grade
) return a
. grade
< b
. grade
; return a
. id
< b
. id
;
} int main ( )
{ int n
, c
; scanf ( "%d%d" , & n
, & c
) ; char id
[ 10 ] , name
[ 10 ] ; int grade
; for ( int i
= 0 ; i
< n
; i
++ ) { scanf ( "%s%s%d" , id
, name
, & grade
) ; rows
[ i
] = { id
, name
, grade
} ; } if ( c
== 1 ) sort ( rows
, rows
+ n
, cmp1
) ; if ( c
== 2 ) sort ( rows
, rows
+ n
, cmp2
) ; if ( c
== 3 ) sort ( rows
, rows
+ n
, cmp3
) ; for ( int i
= 0 ; i
< n
; i
++ ) printf ( "%s %s %d\n" , rows
[ i
] . id
. c_str ( ) , rows
[ i
] . name
. c_str ( ) , rows
[ i
] . grade
) ;
}
1039 Course List for Student (25 分)
題意 :
給出每門課程號參與的學生,詢問每個學生參加了哪些課程
語法 :
auto& ls = students[name];,等效于操作后者
# include <iostream>
# include <unordered_map>
# include <vector>
# include <algorithm>
using namespace std
; # define pb push_back int n
, k
;
unordered_map
< string
, vector
< int >> students
; int main ( )
{ scanf ( "%d%d" , & n
, & k
) ; while ( k
-- ) { int id
, m
; scanf ( "%d%d" , & id
, & m
) ; char name
[ 10 ] ; while ( m
-- ) { scanf ( "%s" , name
) ; students
[ name
] . pb ( id
) ; } } char name
[ 10 ] ; while ( n
-- ) { scanf ( "%s" , name
) ; auto & ls
= students
[ name
] ; printf ( "%s %d" , name
, ls
. size ( ) ) ; sort ( ls
. begin ( ) , ls
. end ( ) ) ; for ( auto l
: ls
) printf ( " %d" , l
) ; puts ( "" ) ; }
}
1075 PAT Judge (25 分)
題意 :
n個用戶(1-n),k個問題(1-k),并給出k個問題分別的分值,m個提交記錄(用戶,問題,所得分值)。 求最后的排名表,總分相同排名并列(但以滿分題數降序輸出,如果仍相同,以id升序),輸出 【排名,用戶名,總分,1-k題分別分值】,沒有提交輸出’-’。同一題多次提交以最高分記錄。如果某用戶未曾提交或者所有提交記錄都不能編譯(-1),不輸出該用戶
語法 :
u_id = u_id_s;表示將char數組轉換成string map中的count返回值如果是0,說明沒有這個左值 students[u_id] = Student(u_id);表示創建一個Student結構體,且賦值函數傳入一個u_id 注意賦值函數寫的方式;Student(){};Student(string _id) : id(_id); id(_id)表示將_id的值賦給id 在結構體中寫函數 bool has_submit() 初始化grade[i]為-2,表示未曾提交 本題,與提交后得0 分和不能編譯 得-1分作區別 注意排名的寫法,一開始rank是1,只有在與上一個的總分不同時(要保證不是第一個元素),rank才會等于i+1,注意不是++
# include <iostream>
# include <unordered_map>
# include <vector>
# include <algorithm>
using namespace std
; const int K
= 6 ; int n
, k
, m
;
int p_score
[ K
] ; struct Student
{ string id
; int grade
[ K
] ; int total
, cnt
; Student ( ) { } Student ( string _id
) : id ( _id
) { for ( int i
= 1 ; i
<= k
; i
++ ) grade
[ i
] = - 2 ; total
= cnt
= 0 ; } bool has_submit ( ) { for ( int i
= 1 ; i
<= k
; i
++ ) if ( grade
[ i
] >= 0 ) return true ; return false ; } void calc ( ) { for ( int i
= 1 ; i
<= k
; i
++ ) { total
+= max ( 0 , grade
[ i
] ) ; if ( grade
[ i
] == p_score
[ i
] ) cnt
++ ; } } bool operator < ( const Student
& t
) const { if ( total
!= t
. total
) return total
> t
. total
; if ( cnt
!= t
. cnt
) return cnt
> t
. cnt
; return id
< t
. id
; }
} ; int main ( )
{ scanf ( "%d%d%d" , & n
, & k
, & m
) ; for ( int i
= 1 ; i
<= k
; i
++ ) scanf ( "%d" , & p_score
[ i
] ) ; unordered_map
< string
, Student
> students
; string u_id
; char u_id_s
[ 10 ] ; int p_id
, score
; while ( m
-- ) { scanf ( "%s%d%d" , u_id_s
, & p_id
, & score
) ; u_id
= u_id_s
; if ( students
. count ( u_id
) == 0 ) students
[ u_id
] = Student ( u_id
) ; students
[ u_id
] . grade
[ p_id
] = max ( students
[ u_id
] . grade
[ p_id
] , score
) ; } vector
< Student
> res
; for ( auto & item
: students
) { auto & s
= item
. second
; if ( s
. has_submit ( ) ) { s
. calc ( ) ; res
. push_back ( s
) ; } } sort ( res
. begin ( ) , res
. end ( ) ) ; for ( int i
= 0 , rank
= 1 ; i
< res
. size ( ) ; i
++ ) { if ( i
&& res
[ i
] . total
!= res
[ i
- 1 ] . total
) rank
= i
+ 1 ; printf ( "%d %s %d" , rank
, res
[ i
] . id
. c_str ( ) , res
[ i
] . total
) ; for ( int j
= 1 ; j
<= k
; j
++ ) { printf ( " " ) ; if ( res
[ i
] . grade
[ j
] != - 2 ) printf ( "%d" , max ( 0 , res
[ i
] . grade
[ j
] ) ) ; else printf ( "-" ) ; } puts ( "" ) ; }
}
1089 Insert or Merge (25 分)
題意 :
插入排序迭代,每次將一個插入元素插入到排好序的輸出序列中,每次迭代插入排序都會從輸入數據中移除一個元素,并在已排好序的序列中找到它所屬的位置,然后將其插入。直到沒有輸入元素剩余為止。 歸并排序的工作方式如下:將未排序的序列劃分為 N 個子序列,每個子序列包含 1 個元素(將 1 個元素的序列視為已排序)。然后重復合并兩個相鄰的子序列以產生新的排序子序列,直到僅剩 1 個子序列為止。 現在,給定初始序列,以及經過某種排序方法多次迭代后的序列,請你判斷我們使用的哪一種排序方法。 假定排序的目標序列總是遞增的。
思路 :
歸并排序,一開始是每個數字自己一組,然后第一輪迭代是兩兩分組,然后先把組內排好序,第二輪是四四分組,然后再下一輪就是八八分組;歸并排序是O(logN)O(logN) O ( l o g N ) 的 如果判斷出不是插入排序,說明是歸并排序 那么怎么樣才能弄出歸并排序的下一輪呢?不如還是從a數組開始一輪輪模擬下去,如果當前等于b數組了,再迭代一輪就是答案;注意循環內是先判斷當前是否相等,然后再迭代一輪,如果剛才判斷相等,現在這個就輸出 sort(a + i, a + min(n + 1, i + len));,不然會段錯誤 注意這里判斷是否是插入排序時,最好是while (p <= n && b[p] >= b[p - 1]) p ++ ;的形式,而不是判斷與下一個,且是大于等于,我們的目的是找到第一個小于前一個數的,不然可能會導致段錯誤
# include <iostream>
# include <algorithm>
using namespace std
; const int N
= 110 ; int n
;
int a
[ N
] , b
[ N
] ; bool check ( )
{ for ( int i
= 1 ; i
<= n
; i
++ ) if ( a
[ i
] != b
[ i
] ) return false ; return true ;
} int main ( )
{ scanf ( "%d" , & n
) ; for ( int i
= 1 ; i
<= n
&& scanf ( "%d" , & a
[ i
] ) ; i
++ ) ; for ( int i
= 1 ; i
<= n
&& scanf ( "%d" , & b
[ i
] ) ; i
++ ) ; int p
= 2 ; while ( p
<= n
&& b
[ p
] >= b
[ p
- 1 ] ) p
++ ; int k
= p
; while ( p
<= n
&& b
[ p
] == a
[ p
] ) p
++ ; if ( p
== n
+ 1 ) { puts ( "Insertion Sort" ) ; while ( k
> 1 && b
[ k
] < b
[ k
- 1 ] ) swap ( b
[ k
] , b
[ k
- 1 ] ) , k
-- ; printf ( "%d" , b
[ 1 ] ) ; for ( int i
= 2 ; i
<= n
; i
++ ) printf ( " %d" , b
[ i
] ) ; } else { puts ( "Merge Sort" ) ; bool match
; k
= 1 ; while ( true ) { match
= check ( ) ; int len
= 1 << k
; for ( int i
= 1 ; i
<= n
; i
+= len
) { sort ( a
+ i
, a
+ min ( n
+ 1 , i
+ len
) ) ; } if ( match
) break ; k
++ ; } printf ( "%d" , a
[ 1 ] ) ; for ( int i
= 2 ; i
<= n
; i
++ ) printf ( " %d" , a
[ i
] ) ; }
}
1098 Insertion or Heap Sort (25 分)
題意 :
插入排序迭代,每次將一個插入元素插入到排好序的輸出序列中,每次迭代插入排序都會從輸入數據中移除一個元素,并在已排好序的序列中找到它所屬的位置,然后將其插入。直到沒有輸入元素剩余為止。 堆排序將其輸入分為已排序和未排序兩個區域,并通過提取未排序區域中的最大元素并將其移至已排序的區域來迭代地縮小未排序的區域。它通過使用堆數據結構而非線性時間搜索來找到最大值。 現在,給定初始序列,以及經過某種排序方法多次迭代后的序列,請你判斷我們使用的哪一種排序方法。運用此方法再進行一次迭代,并在第二行輸出本次迭代后的序列。假定排序的目標序列總是遞增的。
思路 :
堆排序是先把整個數組建成一個大根堆,先把最大值放最后,然后刪掉,然后把次大值放最后,然后刪掉, 所以堆排序實際上從后往前排,后面那幾個已經彈出堆的數,一定是最大的幾個而且排好序的,而前半部分是不一定有序的,前半部分就是這個堆 而插入排序 找規律可以發現前半部分是有序的,后半部分是保持原序的 由于插入排序比堆排序好判斷,所以先判斷它是不是插入排序。先找到無序的第一個,然后如果后半部分原序,說明就是插入排序。 如果確認不是插入排序,那么就是堆排序,先找到分界線,后半部分是最大的k個數,前半部分是一個堆,堆中應該是第一個位置,第一個位置就是前半部分中的最大值;如果一個元素大于堆頂,一定在后半部分,如果等于堆頂,可以在后面;所以我們找大于等于堆頂的元素 堆排序中,大根堆小根堆都能實現從小到大排序,如果用小根堆,那每次把最小值放到序列開頭;如果用大根堆,那就每次把最大值放到序列結尾。 注意down的時候堆的大小是p - 1,不是n,也不是p 這里的堆排序認為與堆內沒有與堆頂元素等值的元素,在堆外
# include <iostream>
using namespace std
; const int N
= 110 ; int n
;
int a
[ N
] , b
[ N
] ; void down ( int u
, int size
)
{ int t
= u
; if ( u
* 2 <= size
&& b
[ t
] < b
[ u
* 2 ] ) t
= u
* 2 ; if ( u
* 2 + 1 <= size
&& b
[ t
] < b
[ u
* 2 + 1 ] ) t
= u
* 2 + 1 ; if ( t
!= u
) { swap ( b
[ t
] , b
[ u
] ) ; down ( t
, size
) ; }
} int main ( )
{ scanf ( "%d" , & n
) ; for ( int i
= 1 ; i
<= n
&& scanf ( "%d" , & a
[ i
] ) ; i
++ ) ; for ( int i
= 1 ; i
<= n
&& scanf ( "%d" , & b
[ i
] ) ; i
++ ) ; int p
= 2 ; while ( p
<= n
&& b
[ p
] >= b
[ p
- 1 ] ) p
++ ; int k
= p
; while ( p
<= n
&& b
[ p
] == a
[ p
] ) p
++ ; if ( p
== n
+ 1 ) { puts ( "Insertion Sort" ) ; while ( k
> 1 && b
[ k
] < b
[ k
- 1 ] ) swap ( b
[ k
] , b
[ k
- 1 ] ) , k
-- ; } else { puts ( "Heap Sort" ) ; p
= n
; while ( p
> 1 && b
[ p
] >= b
[ 1 ] ) p
-- ; swap ( b
[ 1 ] , b
[ p
] ) ; down ( 1 , p
- 1 ) ; } printf ( "%d" , b
[ 1 ] ) ; for ( int i
= 2 ; i
<= n
; i
++ ) printf ( " %d" , b
[ i
] ) ;
}
與50位技術專家面對面 20年技術見證,附贈技術全景圖
總結
以上是生活随笔 為你收集整理的PAT甲级题目翻译+答案 AcWing(排序) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。