Hackerrank 2020 February 2014 解題報告
???????? 比賽鏈接
Sherlock and Watson (20分)
題意:給定一個數組,向右平移K次,然后有Q個詢問,問第x位置上是幾
做法:直接模擬即可

1 #include <iostream> 2 using namespace std; 3 int n,k,q; 4 int a[ 100100 ],b[ 100100 ]; 5 int main(){ 6 ios::sync_with_stdio( 0 ); 7 cin>>n>>k>> q; 8 for ( int i= 0 ;i<n;i++ ){ 9 cin>> a[i]; 10 } 11 for ( int i= 0 ;i<n;i++ ){ 12 b[(i+k)%n] = a[i]; 13 } 14 int x; 15 for ( int i= 0 ;i<q;i++ ){ 16 cin>> x; 17 // int tar = (x+k)%n; 18 cout<<b[x]<< endl; 19 } 20 return 0 ; 21 }
?
Make it Anagram? ( 30分 )
題意:給定兩個字符串,問刪除多少字符后兩個串所含的字符以及對應的個數相同
做法:分別統計每個字符在兩個串中出現的次數,統計差值并求和就是答案

1 #include <cmath> 2 #include <cstdio> 3 #include <vector> 4 #include <iostream> 5 #include <algorithm> 6 #include < string > 7 using namespace std; 8 9 int p[ 255 ],q[ 255 ]; 10 int main() { 11 /* Enter your code here. Read input from STDIN. Print output to STDOUT */ 12 string a,b; 13 cin>>a>> b; 14 for ( char x:a){ 15 p[x]++ ; 16 } 17 for ( char x:b){ 18 q[x]++ ; 19 } 20 int ans = 0 ; 21 for ( int i= ' a ' ;i<= ' z ' ;i++ ){ 22 int tmp = p[i]- q[i]; 23 if (tmp< 0 )tmp=- tmp; 24 ans+= tmp; 25 } 26 cout<<ans<< endl; 27 return 0 ; 28 }
?
Cutting boards ( 40分 )
題意:有一個M*N的木板,要把它分成M*N個單位塊。每次可以沿橫向或縱向切割,連續切割的代價為x1,x2,x..n和y1,y2...yn。求完成任務的最小代價和。
做法:既然所有的鏈接處都要被切開,那么就優先切代價高的,這樣可以減少連續切割的次數,總之就是貪心了。

1 #include <cmath> 2 #include <cstdio> 3 #include <vector> 4 #include <iostream> 5 #include <algorithm> 6 #include <functional> 7 using namespace std; 8 typedef long long ll; 9 const ll mod = (ll)1e9+ 7 ; 10 ll m,n,x[ 1000001 ],y[ 1000001 ]; 11 int main() { 12 ios::sync_with_stdio( 0 ); 13 int t; 14 cin>> t; 15 while (t-- ){ 16 cin>>m>> n; 17 for ( int i= 0 ;i<m- 1 ;i++ ) 18 cin>> x[i]; 19 for ( int i= 0 ;i<n- 1 ;i++ ) 20 cin>> y[i]; 21 sort(x,x+m- 1 ,greater<ll> ()); 22 sort(y,y+n- 1 ,greater<ll> ()); 23 ll ans = 0 ,a= 0 ,b= 0 ; 24 while (a<m- 1 || b<n- 1 ){ 25 if (a<m- 1 ){ 26 if (b<n- 1 ){ 27 if (x[a]> y[b]){ 28 ans = (ans+x[a]*(b+ 1 ))% mod; 29 a++ ; 30 } else { 31 ans = (ans+y[b]*(a+ 1 ))% mod; 32 b++ ; 33 } 34 } else { 35 ans = (ans+x[a]*(b+ 1 ))% mod; 36 a++ ; 37 } 38 } else { 39 ans = (ans+y[b]*(a+ 1 ))% mod; 40 b++ ; 41 } 42 } 43 cout<<ans<< endl; 44 } 45 return 0 ; 46 }
?
Bike Racers (60分)
題意:城市里有N個自行車手和M個自行車,現在要組織K個人比賽,需要他們都找到一輛車,車手的運動速度為1。求最少能在多少時間使得所有車手都到達所選的車?
做法:隨著時間限制的增加,能夠到達的車手一定是不減小的,因此我們可以二分時間t,轉化為判定問題。顯然車和人構成一個二分圖,對于能夠在時限內走到的,我們建一條邊。然后對這個二分圖做最大匹配,看是否有k個匹配。總復雜度O(N^3lg(N))。

1 #include <cmath> 2 #include <cstdio> 3 #include <vector> 4 #include <iostream> 5 #include <algorithm> 6 #include <cstring> 7 using namespace std; 8 typedef long long ll; 9 const ll MAXN = 510 ; 10 ll n,m,k; 11 ll a[MAXN][ 2 ],b[MAXN][ 2 ]; 12 struct node{ 13 ll u,v; 14 ll dis; 15 bool operator <( const node& r) const { 16 return dis< r.dis; 17 } 18 }data[MAXN* MAXN]; 19 ll uN,vN; 20 ll g[MAXN][MAXN]; 21 ll linker[MAXN]; 22 bool used[MAXN]; 23 bool dfs(ll u) 24 { 25 ll v; 26 for (v= 0 ;v<vN;v++ ) 27 if (g[u][v]&&! used[v]) 28 { 29 used[v]= true ; 30 if (linker[v]==- 1 || dfs(linker[v])) 31 { 32 linker[v]= u; 33 return true ; 34 } 35 } 36 return false ; 37 } 38 ll hungary() 39 { 40 ll res= 0 ; 41 ll u; 42 memset(linker,- 1 , sizeof (linker)); 43 for (u= 0 ;u<uN;u++ ) 44 { 45 memset(used, 0 , sizeof (used)); 46 if (dfs(u)) res++ ; 47 } 48 return res; 49 } 50 ll calc(ll x){ 51 memset(g, 0 , sizeof (g)); 52 for (ll i= 0 ;i<=x;i++ ){ 53 ll x = data[i].u; 54 ll y = data[i].v; 55 g[x][y] = 1 ; 56 } 57 return hungary(); 58 } 59 ll solve(){ 60 ll cnt = 0 ; 61 uN = n; 62 vN = m; 63 for (ll i= 0 ;i<n;i++ ){ 64 for (ll j= 0 ;j<m;j++ ){ 65 data[cnt].u= i; 66 data[cnt].v= j; 67 data[cnt].dis = (a[i][ 0 ]-b[j][ 0 ])*(a[i][ 0 ]-b[j][ 0 ])+(a[i][ 1 ]-b[j][ 1 ])*(a[i][ 1 ]-b[j][ 1 ]); 68 cnt++ ; 69 } 70 71 } 72 // cout<<"cnt="<<cnt<<endl; 73 sort(data,data+ cnt); 74 /// / for(ll i=0;i <cnt;i++) 75 // cout <<i<<":"<<data[i].dis<<endl; 76 ll lb=-1,ub=cnt; 77 while (ub-lb> 1 ){ 78 ll mid = (ub+lb)/ 2 ; 79 // cout<<mid<<" "<<calc(mid)<<endl; 80 if (calc(mid)>= k){ 81 ub = mid; 82 } else { 83 lb = mid; 84 } 85 } 86 return data[ub].dis; 87 } 88 int main() { 89 ios::sync_with_stdio( 0 ); 90 cin>>n>>m>> k; 91 for (ll i= 0 ;i<n;i++)cin>>a[i][ 0 ]>>a[i][ 1 ]; 92 for (ll i= 0 ;i<m;i++)cin>>b[i][ 0 ]>>b[i][ 1 ]; 93 ll ans = solve(); 94 cout<<ans<< endl; 95 return 0 ; 96 }
?
Library Query(80分)
題意:帶單點修改的區間第k大
做法:因為數據很小(1 <= N <= 10 4 ,1 <= Q <= 10 4 ),直接分塊就行。修改的時候暴力對相應的塊進行排序,復雜度O(sqrt(n)*lg(n))。查詢的時候通過二分轉化為判斷一個數是第幾大的問題,由于中間部分每個塊內都是排好序的,二分就可以了,對于邊界上的兩塊或者一塊直接暴力統計。復雜度O(sqrt(n)*lg(n)*lg(n))。

1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <vector> 5 #include < set > 6 #include <queue> 7 #include < set > 8 #include <map> 9 #include <cstring> 10 #include <functional> 11 #include <cmath> 12 typedef long long ll; 13 using namespace std; 14 int n,q,cmd,x,y,k; 15 int a[ 10100 ]; 16 int lsize = 128 ; 17 vector< int > v[ 2000 ]; 18 int maxid; 19 int solve( int x, int y, int target){ 20 int idx = x/lsize,idy=y/ lsize; 21 // cerr<<"idx="<<idx<<" idy="<<idy<<endl; 22 int ans = 0 ; 23 for ( int i=x;i<lsize*(idx+ 1 );i++ ){ 24 if (a[i]<= target) 25 ans++ ; 26 } 27 for ( int i=idy*lsize;i<=y;i++ ){ 28 if (a[i]<= target) 29 ans++ ; 30 } 31 for ( int i=idx+ 1 ;i<=idy- 1 ;i++ ){ 32 if (target < v[i][ 0 ]) 33 continue ; 34 else if (target >= v[i].back()) 35 ans+= v[i].size(); 36 else 37 { 38 int tmp = upper_bound(v[i].begin(),v[i].end(),target)- v[i].begin(); 39 ans+= tmp; 40 } 41 42 } 43 return ans; 44 } 45 int main(){ 46 // freopen("int.txt","r",stdin); 47 // freopen("out1.txt","w",stdout); 48 ios::sync_with_stdio( 0 ); 49 int cs; 50 cin>> cs; 51 while (cs-- ){ 52 cin>> n; 53 // lsize = (int)sqrt(n); 54 for ( int i= 0 ;i<=n/lsize;i++ ) 55 v[i].clear(); 56 for ( int i= 0 ;i<n;i++ ) 57 cin>> a[i]; 58 maxid = 0 ; 59 for ( int i= 0 ;i<n;i++ ){ 60 int id = i/ lsize; 61 maxid = id+ 1 ; 62 v[id].push_back(a[i]); 63 } 64 for ( int i= 0 ;i<maxid;i++ ){ 65 sort(v[i].begin(),v[i].end()); 66 } 67 cin>> q; 68 // cout<<"q="<<q<<endl; 69 while (q-- ){ 70 cin>> cmd; 71 if (cmd == 1 ){ 72 cin>>x>> k; 73 x-- ; 74 a[x] = k; 75 int id = x/ lsize; 76 v[id].clear(); 77 for ( int i=id*lsize;i<n&&i<(id+ 1 )*lsize;i++ ){ 78 v[id].push_back(a[i]); 79 } 80 sort(v[id].begin(),v[id].end()); 81 } else { 82 cin>>x>>y>> k; 83 x-- ; 84 y-- ; 85 int idx = x/lsize,idy = y/ lsize; 86 if (idx == idy){ 87 vector< int > tmp(a+x,a+y+ 1 ); 88 sort(tmp.begin(),tmp.end()); 89 cout<<tmp[k- 1 ]<< endl; 90 } else { 91 int lb = - 1 ,ub= 1001 ; 92 while (ub-lb> 1 ){ 93 int mid = (ub+lb)/ 2 ; 94 int rank = solve(x,y,mid); 95 // cerr<<"mid="<<mid<<" rank="<<rank<<endl; 96 if (rank >= k){ 97 ub = mid; 98 } else { 99 lb = mid; 100 } 101 } 102 cout<<ub<< endl; 103 } 104 } 105 } 106 } 107 return 0 ; 108 }
?
?
?
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
