代码源week1

1-1 走路

在这里插入图片描述
分析时间复杂度: N ∗ M N*M NM 正好没超时
所以构造 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值