1-1 走路
分析时间复杂度:
N
∗
M
N*M
N∗M 正好没超时
所以构造
d
p
dp
dp
f
[
i
]
[
j
]
f[i][j]
f[i][j] 表示第
i
i
i 步能否走到
j
j
j
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
const int maxn = 105, maxm = 1e5 + 5;
int n, m;
int f[maxn][maxm];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m;
f[0][0] = 1;
For (i, 1, n) {
int t1, t2;
cin >> t1 >> t2;
For (j, 0, m) {
if (f[i - 1][j]) {
f[i][j + t1] = 1;
f[i][j + t2] = 1;
}
}
}
For (i, 0, m) {
if (f[n][i]) cout << 1; else cout << 0;
}
return 0;
}
1-2 订单编号
这道题需要用到 set 容器,set 是一个有序的关联容器,内部元素按照一定规则排列,有利于对元素的查找和遍历。这里,我们需要用到 set 的 lower_bound() 函数,这个函数的作用是在 set 中查找第一个不小于给定元素的元素。
首先,我们给 c 中传入一个区间(1 到 2e9),表示最开始的时候订单编号可以占用这个区间内的所有整数,同时,我们按照输入的顺序对订单编号进行处理。对于每个订单编号,我们在 c 中查找第一个不小于该编号的元素(使用 lower_bound() 函数),并判断该元素的左端点是否小于等于该编号。
如果左端点小于等于该编号,说明该编号在当前区间内,我们就可以使用该编号。同时,我们还需要将当前区间拆分成两部分,一部分是该编号的左边部分,另一部分是该编号的右边部分。这里用 insert() 函数将这两个部分加入 c 中,并将该编号从 c 中删除。
如果左端点大于该编号,说明该编号已经被使用过了,我们需要找到大于该编号的最小整数作为新的编号。这里我们直接使用该元素的左端点作为新的编号,并将当前区间的右边部分加入 c 中,再将该元素从 c 中删除。
最终,我们输出处理后的订单编号即可。
时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),主要是由于 set 容器的插入、查找和删除操作的时间复杂度均为 O ( l o g n ) O(logn) O(logn)。
lower_bound() 和 upper_bound() 是 set 和 map 容器的成员函数,用于在有序的容器中查找给定值的位置。
lower_bound() 函数会返回第一个不小于给定值的元素的位置,如果所有元素都小于给定值,则返回容器的 end() 迭代器。
upper_bound() 函数会返回第一个大于给定值的元素的位置,如果所有元素都小于等于给定值,则返回容器的 end() 迭代器。
注意 insert 的时候会出现 l > r 的情况。
注意第一次 insert 的时候要开两倍的 1e9,防超范围。
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
const int maxn = 5e5 + 5;
int n, t;
int a[maxn];
set <pair<int, int> > st;
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n;
st.insert({2e9, 1});
For (i, 1, n) {
cin >> t;
auto iter = st.lower_bound({t, 0});
if (iter->second <= t) {
cout << t << " ";
if (iter->second <= t - 1)
st.insert({t - 1, iter->second});
if (t + 1 <= iter->first)
st.insert({iter->first, t + 1});
st.erase(iter);
} else {
cout << iter->second << " ";
if (iter->second + 1 <= iter->first)
st.insert({iter->first, iter->second + 1});
st.erase(iter);
}
}
return 0;
}
1-3 饿饿 饭饭
二分查找,找到
k
k
k 份饭条件下,能进行整个轮回的次数,再单独处理剩下的饭所分发的人
学习到更好的二分写法:
w
h
i
l
e
(
l
+
1
<
r
)
while (l + 1 < r)
while(l+1<r)
l
=
m
i
d
l=mid
l=mid
r
=
m
i
d
r=mid
r=mid 最后答案是
l
l
l
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
ll n, k;
const int maxn = 1e5 + 5;
int a[maxn];
ll s[maxn];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> k;
For (i, 1, n) cin >> a[i], s[i] = s[i - 1] + a[i];
if (s[n] < k ) { puts("-1"); exit(0); }
ll l = 0, r = 1e9;
while (l + 1 < r) {
ll mid = l + r >> 1;
ll sum = 0;
For (i, 1, n) {
if (a[i] <= mid) sum += a[i];
else sum += mid;
}
if (sum > k) r = mid;
else l = mid;
}
ll sum = 0;
For (i, 1, n) {
if (a[i] <= l) sum += a[i];
else sum += l;
}
ll res = k - sum;
queue <int> q;
int cnt = 0;
For (i, 1, n) {
if (a[i] >= l + 1) {
if (cnt >= res) {
cout << i << " ";
}
else {
cnt++;
if (a[i] > l + 1)
q.push(i);
}
}
}
while (!q.empty()) {
cout << q.front() << " ";
q.pop();
}
return 0;
}
1-4 任务分配
导弹拦截 变型
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
const int maxn = 1e3 + 5;
struct node {
int s, e, w;
} a[maxn];
int f[maxn];
int n;
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n;
For (i, 1, n) {
cin >> a[i].s >> a[i].e >> a[i].w;
}
sort(a + 1, a + 1 + n, [](node a, node b){
return (a.s < b.s || (a.s == b.s && a.e < b.e) || (a.s == b.s && a.e == b.e && a.w < b.w));
});
For (i, 1, n) f[i] = a[i].w;
For (i, 1, n) {
For (j, 1, i - 1) {
if (a[j].e <= a[i].s && f[j] + a[i].w > f[i]) {
f[i] = f[j] + a[i].w;
}
}
}
int ans = 0;
For (i, 1, n) {
ans = max(ans, f[i]);
}
cout << ans;
return 0;
}
1-Rest 其余水题
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
int n;
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n;
For (i, 1, n) {
For (j, 1, n) {
For (l, 1, n) {
if (((i == l || i == n - l + 1) && (j >= l || j <= n - l + 1))
|| ((j == l || j == n - l + 1) && (i >= l || i <= n - l + 1)))
{
if (l % 2 == 1) cout << '+'; else cout << '.';
break;
}
}
}
cout << '\n';
}
return 0;
}
/*
分析时间复杂度:N*M 正好没超时
所以构造dp f[i][j] 表示第i步能否走到j
*/
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
const int maxn = 105, maxm = 1e5 + 5;
int n, m;
int f[maxn][maxm];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m;
f[0][0] = 1;
For (i, 1, n) {
int t1, t2;
cin >> t1 >> t2;
For (j, 0, m) {
if (f[i - 1][j]) {
f[i][j + t1] = 1;
f[i][j + t2] = 1;
}
}
}
For (i, 0, m) {
if (f[n][i]) cout << 1; else cout << 0;
}
return 0;
}
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
const int maxn = 205;
unordered_map <string, ll> mp;
unordered_map <string, ll> st;
string ss[205];
int n, m, k;
string s;
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m >> k;
For (i, 1, n) {
cin >> s;
st.insert({s, 0});
ss[i] = s;
}
For (i, 1, m) {
int sc;
cin >> s >> sc;
mp.insert({s, sc});
}
For (i, 1, k) {
string s2, s3;
cin >> s >> s2 >> s3;
if (s3 == "WA") continue;
if (st.find(s) == st.end()) continue;
st[s] += mp[s2];
}
For (i, 1, n) {
cout << ss[i] << " " << st[ss[i]] << '\n';
}
return 0;
}
/*
纯模拟
*/
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
struct node {
int x, y;
} a[6];
int vis[20], vi[20];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
For (i, 1, 5) {
cin >> a[i].x;
vis[a[i].x]++;
}
For (i, 1, 5) {
cin >> a[i].y;
vi[a[i].y]++;
}
sort(a + 1, a + 6, [](node a, node b){
return (a.x < b.y);
});
if (a[1].x + 1 == a[2].x && a[2].x + 1 == a[3].x && a[3].x + 1 == a[4].x &&
a[4].x + 1 == a[5].x && a[1].y == a[2].y && a[1].y == a[3].y && a[1].y == a[4].y && a[1].y == a[5].y)
{ if (a[5].x == 14)
cout << "ROYAL FLUSH";
else cout << "STRAIGHT FLUSH";
return 0; }
For (i, 2, 14) {
if (vis[i] >= 4) {cout << "FOUR OF A KIND";return 0;}
}
bool j1 = 0, j2 = 0;
For (i, 2, 14) {
if (vis[i] == 3) j1 = 1;
if (vis[i] == 2) j2 = 1;
}
if (j1 && j2) {cout << "FULL HOUSE"; return 0; }
For (i, 1, 4) {
if (vi[i] == 5) { cout << "FLUSH"; return 0; }
}
if (a[1].x + 1 == a[2].x && a[2].x + 1 == a[3].x && a[3].x + 1 == a[4].x &&
a[4].x + 1 == a[5].x) {
cout << "STRAIGHT"; return 0;
}
For (i, 2, 14) {
if (vis[i] == 3) { return 0; }
}
cout << "FOLD";
return 0;
}
/*
路径DP
*/
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
const int mod = 1e9 + 7, maxn = 105;
int n;
ll a[maxn][maxn], f[maxn][maxn];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n;
For (i, 1, n) {
For (j, 1, n) {
cin >> a[i][j];
if (a[i][j]) {
f[i][j] = f[i - 1][j] * a[i - 1][j] + f[i][j - 1] * a[i][j - 1];
f[i][j] %= mod;
}
if (i == 1 && j == 1) f[i][j] = 1;
}
}
cout << f[n][n];
return 0;
}
/*
板子题
*/
#include <bits/stdc++.h>
#define For(i, a, b) for (int i = a; i <= b; i++)
#define _For(i, a, b) for (int i = a; i >= b; i--)
typedef long long ll;
using namespace std;
const int maxn = 1e3 + 5;
int n;
int a[maxn], f[maxn];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n;
For (i, 1, n) cin >> a[i];
For (i, 1, n) f[i] = a[i];
For (i, 1, n) {
For (j, 1, i - 1) {
if (a[i] > a[j] && f[i] < f[j] + a[i]) f[i] = f[j] + a[i];
}
}
int ans = 0;
For (i, 1, n) {
ans = max(ans, f[i]);
}
cout << ans;
return 0;
}