IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 2022年山大地纬杯”第十二届山东省ICPC大学生程序设计竞赛赛后总结 -> 正文阅读

[数据结构与算法]2022年山大地纬杯”第十二届山东省ICPC大学生程序设计竞赛赛后总结

总结:

这场比赛前心里多上还是有点忐忑的, 虽然我觉得这场比赛能够拿到牌子, 但是鉴于我们队之前参加训练赛时总是会被一道题卡住并在赛后突然顿悟ac的情况, 我怕我们这次比赛也会因为卡在一道关键性的题目上而最终一无所获,事实上比赛时差点就这样了。 我们AC的三道题目中其中有两道题都是因为考虑不周或粗心大意而耗费了很长的时间才做出来。 A题我们当时没有考虑到特判的情况以至于久久未能过题, 好在最终能够反应过来找到特判情况最后AC过了; 另一个卡的H题也是,我们一直没有留意到我们的数据范围开小了, 以至于看代码的中间过程看的差点怀疑人生, 不过也是万幸在比赛结束前发现了这个错误, 最终保住了牌子。 事实上当时无论A还是H, 我们的解题思路都是对的, 毕竟这两道题并不难, 但是就是因为粗心大意和思虑不周,让我们错失了更多解决其他问题的机会 (果然还是我们太菜了😭) 。不过虽然过程并不如意, 但是收获还是有的, 更重要的是在比赛过程中我们队的心态一直保持的很好, 没有因为遇到挫折而变得焦虑不安大脑短路 (思路一直很清晰, 解题过程觉得崩对, 但奈何眼神不太好🙁) , 所以不管怎么说, 这次比赛我们还是成功的。
好了, 下面我把我们的出的题的思路写一下。

A题:

题目链接

思路:

首先用sum 存 (1-n)全部整数的和, 然后求出sum-17的差。
如果(1-n)中有一个数 i 是负数, 即运算时对 i 进行减法操作, 那么此时(1-n)的和就是 sum - 2i, 即sum 减去原先的正 i 加上 改后的 -i。
这样的话, 要求出题目中的结果只需要把能够组成(sum-17)/ 2 的整数进行减法操作就行了, 当然, 如果(sum-17) / 2 为奇数, 那么我们可以把 1 单独拿出来用 1
(其他数的+,-运算)。
至于求那些用做减法的数, 我们可以从 n开始遍历, 让tmp = (sum-17)/ 2 , 如果tmp > i + 1, 那么 tmp -= i。(一定是tmp > i+1, 用来处理提出 1 这个数的情况)

代码:
#include <bits/stdc++.h>
#define _max(a, b) ((a) > (b) ? (a) : (b))
#define _min(a, b) ((a) < (b) ? (a) : (b))
#define fi(i, a, b) for(int i = a; i <= b; ++i)
#define fd(i, a, b) for(int i = a; i >= b; --i)
#define gc getchar
#define pc putchar
#define il inline
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const int mode = 1e9+7;
const double eps = 1e-6;


int n;
int a[maxn];
int main() {
    // fi(n, 1, 50) {
        cin >> n;
        memset(a, 0, sizeof(a));
        ll sum = 0;
        ll tmp = 0;
        fi(i, 1, n) {
            sum += i;
        }
        // cout << sum << " *** " << endl;
        tmp = sum - 17;
        
        ll tmp1 = 0;
        if (tmp < 0) {
            if (n == 5) {
                cout << "1+3+2*4+5";
            }
            else if (n == 4) {
                cout << "(4+1)*3+2";
            }
            else 
                cout << -1 << endl;
            // continue;
        }
        else{
            bool bl = 0;
            if (tmp % 2) {
                cout << 1 << "*(";
                bl = 1;
            }
            else cout << 1;
            tmp /= 2;
            fd(i, n, 2) {
                if (!tmp) break;
                if (tmp >= i && tmp != i+1) {
                    tmp -= i;
                    a[i] = 1;
                    tmp1 += i;
                }
            }
            fi(i, 2, n) {
                if (a[i]) {
                    cout << "-";
                }
                else {
                    if (i > 2 || (i == 2 && !bl)) {
                        cout << "+";
                    }
                }
                cout << i;
            }
            if (bl ) cout << ")";
        }   
    //     cout << endl << sum << " - " << tmp1*2 << " = " << (sum-tmp1*2) << endl;
    //     cout << endl << tmp << " **** " << endl << endl;
        
    // }
    return 0;
}

H题:

题目链接

思路:

每次移动之后都把每个点按 x,y坐标排序, 然后遍历一遍,找到一段连续的区间里面每个点的 x 和 y 的坐标都相同, 然后, 这样的单段区间就是相遇的所有点, 一段区间的对数是n*(n-1)/ 2, 按这种方式遍历统计下就可以了。

代码:
#include <bits/stdc++.h>
#define int long long
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int N = 4000;
struct node{
    int x, y;
}a[N], b[N];
bool cmp(node a, node b){
    if(a.x!=b.x) return a.x < b.x;
    return a.y < b.y;
}
int n, m, k, T;
char s[N][N];
signed main(){
    ios;
    cin >> n >> m >> k >> T;
    for(int i=1;i<=k;i++){
        cin >> a[i].x >> a[i].y;
    }
    for(int i=1;i<=k;i++) cin >> (s[i] + 1);
    for(int j=0;j<=T;j++){
        int num = 0;
        if(j==0){
        for(int i=1;i<=k;i++) b[i] = a[i];
             sort(b+1, b+k+1, cmp);
            for(int i=1;i<k;i++){
                if(b[i].x==b[i+1].x && b[i].y==b[i+1].y){
                    int cnt = 1, p = i+1;
                    while(b[p].x==b[i].x&&b[p].y==b[i].y&&p<=k){
                        p++, cnt++;
                    }
                    i = p - 1;
                    num += cnt*(cnt-1)/2;
                }
            }
        }else{
            for(int i=1;i<=k;i++){
                if(s[i][j]=='R') a[i].y++;
                else if(s[i][j]=='L') a[i].y--;
                else if(s[i][j]=='U') a[i].x--;
                else if(s[i][j]=='D') a[i].x++;
            }
            for(int i=1;i<=k;i++) b[i] = a[i];
            sort(b+1, b+k+1, cmp);
            for(int i=1;i<k;i++){
                if(b[i].x==b[i+1].x && b[i].y==b[i+1].y){
                    int cnt = 1, p = i+1;
                   
                    while(b[p].x==b[i].x&&b[p].y==b[i].y){
                        p++, cnt++;
                    }
                    num += cnt*(cnt-1)/2;
                    i = p - 1;
                }
            }
        }
        cout << num << '\n';
    }
    return 0;
}

K题:

思路:

我们是先用完全背包预处理了一定范围的结果, 这个范围不用太大, 当然我们预处理了1e5的数据, 但是实际只用到了前一百个数据, (事实上只用两三个数据应该就可以, 但是保险起见我们开大了一点)
以为要想硬币最少, 那么你用到的面值最大的硬币个数应该最多,用到最后剩余金额不足最大的面值, 这时再用小面值来凑, 要是小面值凑不出来, 就少用一个大面值硬币, 扩大一下范围再凑, 找到能凑出这个金额, 并且硬币最少的情况, 两人比较输出即可。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+10, maxn = 1e6;
typedef long long ll;
ll f1[N], f2[N];
int a[] = {0, 2, 3, 17, 19};
int b[] = {0, 5, 7, 11, 13};
int main(){
    memset(f1, 0x3f, sizeof f1);
    memset(f2, 0x3f, sizeof f2);
    f1[0] = f2[0] = 0;
    for(int i=1;i<=4;i++)
        for(int j=a[i];j<=maxn;j++)
            f1[j] = min(f1[j], f1[j-a[i]]+1);
    for(int i=1;i<=4;i++)
        for(int j=b[i];j<=maxn;j++)
            f2[j] = min(f2[j], f2[j-b[i]]+1);
    int q; 
    scanf("%d", &q);
    while(q--){
        ll x;
        scanf("%lld",&x);
        ll tmp1 = x/19;
        ll md1 = x%19;
        ll tmp2 = x/13;
        ll md2 = x%13;
        ll mi1 = 0x3f3f3f3f;
        ll mi2 = 0x3f3f3f3f;
        for (int i = 0; i <= min(100ll, tmp1); ++i) {
            mi1 = min(f1[(i*19+md1)]+tmp1-i, mi1);
        }
        for (int i = 0; i <= min(100ll, tmp2); ++i) {
            mi2 = min(f2[(i*13+md2)]+tmp2-i, mi2);
        }
        if(mi1==0x3f3f3f3f&&mi2==0x3f3f3f3f) cout << -1 << '\n';
        else if(mi1==mi2) cout << "both" << '\n';
        else{
            if(mi1 < mi2) cout << "A" << '\n';
            else cout << "B" << '\n';
        }
    }
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:26:10  更:2022-06-01 15:27:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:39:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码