生活随笔
收集整理的這篇文章主要介紹了
2021算法竞赛入门班第二节课【递归、分治、二分】练习题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- 華華給月月準備禮物【二分】
- The Biggest Water Problem【模擬】
- Bits【遞歸模擬 / 未完成】
- [NOIP2004]FBI樹【樹的后序遍歷】
- [USACO 2009 Dec S]Music Notes【二分+前綴和】
- [NOIP2009]分數線劃定【模擬】
- 逆序數【歸并排序】
- 逆序對【組合數 / 推式子】
- 完全平方數【二分】
- [USACO 2010 Feb S]Chocolate Eating【二分】
- 第k小數【快排】
華華給月月準備禮物【二分】
https://ac.nowcoder.com/acm/problem/23049
就是一個常見的二分模板
#include<bits/stdc++.h>
using namespace std
;
typedef long long int LL
;
const int N
=1e5+10;
LL a
[N
],n
,k
;
bool check(int x
)
{int cnt
=0;for(int i
=0;i
<n
;i
++) cnt
+=a
[i
]/x
;if(cnt
>=k
) return true;return false;
}
int main(void)
{cin
>>n
>>k
;for(int i
=0;i
<n
;i
++) cin
>>a
[i
];LL l
=0,r
=1e9+10;while(l
<r
){LL mid
=l
+r
+1>>1;if(check(mid
)) l
=mid
;else r
=mid
-1;}cout
<<l
;return 0;
}
The Biggest Water Problem【模擬】
https://ac.nowcoder.com/acm/problem/15173
#include<bits/stdc++.h>
using namespace std
;
int main(void)
{int n
; cin
>>n
;while(n
>=10){int sum
=0;while(n
) sum
+=n
%10,n
/=10;n
=sum
;}cout
<<n
;return 0;
}
Bits【遞歸模擬 / 未完成】
https://ac.nowcoder.com/acm/problem/201605
[NOIP2004]FBI樹【樹的后序遍歷】
https://ac.nowcoder.com/acm/problem/16660
#include<bits/stdc++.h>
using namespace std
;
int n
;
string s
;
void dfs(string s
)
{if(s
.size()>1){dfs(s
.substr(0,s
.size()/2));dfs(s
.substr(s
.size()/2));}int cnt0
=0,cnt1
=0;for(int i
=0;i
<s
.size();i
++) if(s
[i
]=='0') cnt0
++;else cnt1
++;if(cnt0
&&cnt1
) cout
<<'F';else if(cnt0
&&!cnt1
) cout
<<'B';else cout
<<'I';
}
int main(void)
{cin
>>n
>>s
;dfs(s
);return 0;
}
[USACO 2009 Dec S]Music Notes【二分+前綴和】
https://ac.nowcoder.com/acm/problem/24866
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e5+10;
int a
[N
],n
,m
;
int main(void)
{cin
>>n
>>m
;for(int i
=1;i
<=n
;i
++) cin
>>a
[i
],a
[i
]+=a
[i
-1];while(m
--){int x
; cin
>>x
;int l
=1,r
=n
;while(l
<r
){int mid
=l
+r
>>1;if(a
[mid
]>=(x
+1)) r
=mid
;else l
=mid
+1;}cout
<<l
<<endl
;}
}
[NOIP2009]分數線劃定【模擬】
https://ac.nowcoder.com/acm/problem/16625
#include<cstdio>
#include<algorithm>
using namespace std
;
struct student
{int sum
;int id
;
}s
[5005];
bool cmp(student a
,student b
)
{if(a
.sum
!=b
.sum
)return a
.sum
>b
.sum
;elsereturn a
.id
<b
.id
;}
int main(void)
{int n
,m
;int end_number
;int end_score
;int i
;scanf("%d %d",&n
,&m
);end_number
=m
*1.5;for(i
=0;i
<n
;i
++){scanf("%d %d",&s
[i
].id
,&s
[i
].sum
);}sort(s
,s
+n
,cmp
);end_score
=s
[end_number
-1].sum
;for(i
=end_number
;i
<n
;i
++){if(s
[i
].sum
==end_score
)end_number
++;elsebreak;}printf("%d %d\n",end_score
,end_number
);for(i
=0;i
<end_number
;i
++){printf("%d %d\n",s
[i
].id
,s
[i
].sum
);}return 0;
}
逆序數【歸并排序】
https://ac.nowcoder.com/acm/problem/15163
#include<bits/stdc++.h>
using namespace std
;
typedef long long int LL
;
const int N
=1e5+10;
LL a
[N
],b
[N
],n
,res
;
void merge_sort(int l
,int r
)
{if(l
>=r
) return;int i
=l
,mid
=l
+r
>>1,j
=mid
+1;merge_sort(l
,mid
),merge_sort(mid
+1,r
);int k
=0;while(i
<=mid
&&j
<=r
) {if(a
[i
]<=a
[j
]) b
[k
++]=a
[i
++];else{res
+=mid
-i
+1;b
[k
++]=a
[j
++];}}while(i
<=mid
) b
[k
++]=a
[i
++];while(j
<=r
) b
[k
++]=a
[j
++];for(int i
=l
,j
=0;i
<=r
;i
++,j
++) a
[i
]=b
[j
];
}
int main(void)
{cin
>>n
;for(int i
=0;i
<n
;i
++) cin
>>a
[i
];merge_sort(0,n
-1);cout
<<res
;return 0;
}
逆序對【組合數 / 推式子】
https://ac.nowcoder.com/acm/problem/14731
#include<bits/stdc++.h>
using namespace std
;
typedef long long int LL
;
const int mod
=1e9+7;
LL
quick_mi(LL a
,LL b
, LL p
)
{LL sum
=1;while(b
){if(b
&1) sum
=sum
*a
%p
; b
>>=1;a
=(a
*a
)%p
;}return sum
%p
;
}
int main(void)
{LL n
; cin
>>n
;if(n
==1) cout
<<0;else if(n
==2) cout
<<1;else cout
<<(n
%mod
)*((n
-1)%mod
)%mod
*quick_mi(2,n
-3,mod
)%mod
;return 0;
}
完全平方數【二分】
https://ac.nowcoder.com/acm/problem/14733
#include<bits/stdc++.h>
using namespace std
;
typedef long long int LL
;
vector
<LL
>ve
;
int main(void)
{for(LL i
=0;i
<=1e5;i
++) ve
.push_back(i
*i
);int n
; cin
>>n
;while(n
--){LL a
,b
,l
,r
; cin
>>a
>>b
;int len1
=0,len2
=0;l
=0,r
=ve
.size()-1;while(l
<r
){int mid
=l
+r
>>1;if(ve
[mid
]>=a
) r
=mid
;else l
=mid
+1;}len1
=l
;l
=0,r
=ve
.size()-1;while(l
<r
){int mid
=l
+r
+1>>1;if(ve
[mid
]<=b
) l
=mid
;else r
=mid
-1;}len2
=l
;cout
<<len2
-len1
+1<<endl
;}return 0;
}
[USACO 2010 Feb S]Chocolate Eating【二分】
https://ac.nowcoder.com/acm/problem/24724
注意的一點是: 開一個備用數組 只有滿足條件時再保存答案 避免數組錯亂保存
還需注意的是,當我們滿足時,如果巧克力吃的天數不夠,那么統一的最后一天吃。
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e5+10;
typedef unsigned long long int LL
;
LL a
[N
],s
,n
,m
;
LL ans
[N
];
bool check(LL mid
)
{LL len
=1,temp
=0;LL backup
[N
]={0};for(int i
=1,j
=1;i
<=m
;i
++){while(temp
<mid
&&j
<=n
) temp
+=a
[j
],backup
[j
]=i
,j
++;if(temp
<mid
) return false;temp
/=2;}memcpy(ans
,backup
,sizeof ans
);return true;
}
int main(void)
{cin
>>n
>>m
;for(int i
=1;i
<=n
;i
++) cin
>>a
[i
],s
+=a
[i
];LL l
=0,r
=s
;while(l
<r
){LL mid
=l
+r
+1>>1;if(check(mid
)) l
=mid
;else r
=mid
-1;}cout
<<l
<<endl
;for(int i
=1;i
<=n
;i
++) {if(!ans
[i
]) ans
[i
]=m
;cout
<<ans
[i
]<<endl
;}return 0;
}
第k小數【快排】
https://ac.nowcoder.com/acm/problem/207028
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e7+10;
int a
[N
],t
,n
,k
;
inline int read(){int x
= 0, f
= 1;char ch
= getchar();while(ch
< '0' || ch
> '9'){if (ch
== '-')f
= -1;ch
= getchar();}while(ch
>= '0' && ch
<= '9'){x
= (x
<<1) + (x
<<3) + (ch
^48);ch
= getchar();}return x
* f
;
}
int main(void)
{t
=read();;while(t
--){n
=read(); k
=read();for(int i
=1;i
<=n
;i
++) a
[i
]=read();sort(a
+1,a
+n
+1);printf("%d\n",a
[k
]);}return 0;
}
總結
以上是生活随笔為你收集整理的2021算法竞赛入门班第二节课【递归、分治、二分】练习题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。