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元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

