Hackerrank 2020 February 2014 解题报告

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

Library Query(80分)

题意:带单点修改的区间第k大

做法:因为数据很小(1 <= N <= 104 ,1 <= Q <= 104 ),直接分块就行。修改的时候暴力对相应的块进行排序,复杂度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 }
View Code

 

 

 

 

 

posted @ 2014-02-28 23:50  thermal  阅读(939)  评论(0编辑  收藏  举报