一、二分
1.P1102

二分+排序
cpp
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
long long a[N];
int main(){
long long n, c; cin>>n>>c;
for(int i = 0; i < n ;i++){
cin>>a[i];
}
sort(a, a + n);
long long cnt = 0;
for(int i =0 ; i < n ; i++){
long long target = a[i] + c;
cnt += upper_bound(a , a+ n,target) - lower_bound(a,a+n,target);//第一个大于目标值的索引值减去第一个大于等于目标值的索引值,累加下来就是统计素有符合题意的个数。
}
cout<<cnt<<'\n';
return 0;
}
2.P1182
二分+贪心


cpp
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 5;
ll a[N];
int n, m;
bool check(ll limit){
ll sum= 0;
ll cnt = 1;
for(int i = 0; i < n; i++){
if(sum + a[i] <= limit){
sum += a[i];
}
else{
cnt++;
sum = a[i];
}
}
return cnt <= m;
}
int main() {
cin>>n>>m;
ll l = 0, r = 0;
for(int i =0 ; i<n; i++){
cin>>a[i];
l = max(l,a[i]);//左边界
r += a[i];//右边界
}
while(l < r){
ll mid = l +(r - l) / 2;
if(check(mid)){
r = mid;
}
else {
l = mid + 1;
}
}
cout<<l<<'\n';
return 0;
}
3.P1873


二分答案
cpp
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
using ll = long long;
ll a[N];
ll n,m;
bool check(ll mid){
ll wood = 0;
for(int i = 0; i< n; i++){
if(mid < a[i]){
wood += a[i] - mid;
}
if(wood >= m)
return true;
}
return wood >= m;
}
int main(){
cin>>n>>m;
ll l = 0, r = 0;
for(int i = 0; i < n; i++){
cin>>a[i];
r = max(r,a[i]);
}
ll ans = 0;
while(l <= r){
ll mid = l + (r - l) /2;
if(check(mid)){
ans = mid;
l = mid + 1;
}
else{
r = mid - 1;
}
}
cout<<ans<<'\n';
return 0;
}
二、搜索
DFS
1.P1451


cpp
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
char grid[N][N];//定义的是字符串二维数组
bool vis[N][N];
int n, m;
void dfs(int x, int y){
int dx[4] = {-1, 1, 0, 0 };
int dy[4] = {0, 0, -1, 1 };
vis[x][y] = true;
for(int i = 0; i < 4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx >= 0 && nx < n &&ny >=0 &&ny < m){
if(grid[nx][ny] != '0' && !vis[nx][ny]){
dfs(nx,ny);
}
}
}
return;
}
int main(){
cin>>n>>m;
int cnt = 0;
for(int i = 0; i < n; i++){
string s;
cin>>s;
for(int j = 0; j <m; j++){
grid[i][j] = s[j];
}
}
for(int i = 0; i< n; i++){
for(int j = 0; j < m ;j++){
if(grid[i][j] != '0' && !vis[i][j])
{
dfs(i,j);
cnt++;
}
}
}
cout<<cnt<<'\n';
return 0;
}
BFS
1.P1443|马的遍历

适用于c++11版本:
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m, x, y;
cin >> n >> m >> x >> y;
x--; y--;
vector<vector<int>> f(n, vector<int>(m, -1));
queue<pair<int,int>> q;
q.push({x,y});
f[x][y] = 0;
int dx[8] = {1,1,2,2,-1,-1,-2,-2};
int dy[8] = {2,-2,1,-1,2,-2,1,-1};
while(!q.empty()){
pair<int,int> cur = q.front(); q.pop();
int a = cur.first;
int b = cur.second;
for(int i = 0; i < 8; i++){
int nx = a + dx[i];
int ny = b + dy[i];
if(nx >= 0 && nx < n && ny >= 0 && ny < m && f[nx][ny] == -1){
f[nx][ny] = f[a][b] + 1;
q.push({nx,ny});
}
}
}
for(auto &row : f){
for(int i = 0; i < row.size(); i++){
cout << row[i];
if(i != row.size()-1) cout << " ";
}
cout << "\n";
}
return 0;
}
三、贪心
1.P1094


cpp
#include<bits/stdc++.h>
using namespace std;
const int N = 3e4+5;
int a[N];
int main(){
int w,n ; cin>>w>>n;
for(int i =0 ; i < n; i++) cin>>a[i];
sort(a,a+n);
int l = 0, r = n - 1;
int cnt = 0;
while(l <= r){
if(a[l] + a[r] <= w){
l++;
}
r--;
cnt++;
}
cout<<cnt<<'\n';
return 0;
}
2.P1803


cpp
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int a[N];
struct t{
int start;
int end;
};
bool cmp(const t &a,const t &b){
return a.end < b.end;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n; cin>>n;
vector<t> ts(n);
for(int i =0; i <n ;i++){
cin>>ts[i].start>>ts[i].end;
}
int cnt = 0;
int l_end = -1;
sort(ts.begin(),ts.end(),cmp);
for(int i = 0; i< n; i++){
if(ts[i].start >= l_end){
cnt++;
l_end = ts[i].end;
}
}
cout<<cnt<<'\n';
return 0;
}
四、数学
埃氏筛
cpp
// 质数筛
for (int i = 2; i * i <= m; i++)
if (isPrime[i])
for (int j = i * i; j <= m; j += i)
isPrime[j] = false;
// 前缀和
pre[i] = pre[i - 1] + isPrime[i];
// 查询
ans = pre[r] - pre[l - 1];
1.P1865


部分超时
cpp
#include<bits/stdc++.h>
using namespace std;
bool prime(int x){
if(x < 2) return false;
for(int i = 2; i*i <= x; i++){
if(x % i ==0) return false;
}
return true;
}
int cnt;
int main(){
int n,m; cin>>n>>m;
int l, r;
for(int i =0 ; i < n; i++){
cin>>l>>r;
if(l < 1 || r > m){
cout<<"Crossing the line"<<'\n';
continue;
}
cnt = 0;
for(int j = l; j <= r; j++){
if(prime(j)){
cnt++;
}
}
cout<<cnt<<'\n';
}
return 0;
}
使用埃氏筛
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
// 1. 埃拉托斯特尼筛法预处理质数
vector<bool> isPrime(m + 1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= m; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= m; j += i) {
isPrime[j] = false;
}
}
}
// 2. 前缀和,count[i]表示[1..i]质数数量
vector<int> count(m + 1, 0);
for (int i = 1; i <= m; i++) {
count[i] = count[i - 1] + (isPrime[i] ? 1 : 0);
}
// 3. 查询每个区间
int l, r;
for (int i = 0; i < n; i++) {
cin >> l >> r;
if (l < 1 || r > m) {
cout << "Crossing the line\n";
} else {
cout << count[r] - count[l - 1] << "\n";
}
}
return 0;
}
2.P1029


cpp
#include<bits/stdc++.h>
using namespace std;
int gcd(int n, int m){
if(m == 0) return n;
return gcd(m, n % m);
}
int main(){
int x, y;
cin>>x>>y;
int cnt = 0;
for(int i = x; i <= y; i++){
if(x * y % i == 0 && gcd(i,x * y / i) == x) cnt++;
}
cout<<cnt<<'\n';
return 0;
}