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

 

 

 

 

 

你可能感兴趣的:(rank)