当前位置:首页 > 技术 > 正文内容

USACO铜组三道题解析

访客 技术 2026年6月9日 1

第一题:ABC问题

给定七个整数,它们是 ABCA+BB+CC+AA+B+C 的某种排列,要求还原出 ABC 的值(满足 A ≤ B ≤ C)。

由于所有数均为正整数,A+B+C 必然是这七个数中最大的。而 AB 分别是我我们能确定的最小和次小的数。排序后,最大值即为三数之和,最小两个数即为 AB,进而可求出 C

#include <bits/stdc++.h>
using namespace std;

int val[8], sum, first, second, third;

int main() {
    freopen("abc.in", "r", stdin);
    freopen("abc.out", "w", stdout);
    for (int i = 1; i <= 7; i++) {
        cin >> val[i];
    }
    sort(val + 1, val + 8);
    sum = val[7];
    first = val[1];
    second = val[2];
    third = sum - first - second;
    cout << first << " " << second << " " << third << endl;
    return 0;
}

第二题:雏菊花环

给定 N 朵花的花瓣数,统计所有连续子数组中,存在某个元素恰好等于该子数组平均值的子数组个数。

数据范围较小,可以直接枚举所有子区间。利用前缀和快速计算区间和,再判断平均值是否为整数,最后检查该区间内是否存在等于该平均值的元素。

初始的 O(N³) 做法会枚举每个子区间后,再遍历区间内每个元素进行判断。可以优化为 O(N²):在向右扩展右端点时,用哈希表维护当前区间内各花瓣数的出现次数,从而 O(1) 判断平均值是否存在。

#include <bits/stdc++.h>
using namespace std;

int petal[105], prefix[105], n, result;
bool freq[1005];

int main() {
    freopen("daisy.in", "r", stdin);
    freopen("daisy.out", "w", stdout);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> petal[i];
        prefix[i] = prefix[i - 1] + petal[i];
    }
    for (int left = 1; left <= n; left++) {
        memset(freq, 0, sizeof(freq));
        for (int right = left; right <= n; right++) {
            freq[petal[right]] = true;
            int total = prefix[right] - prefix[left - 1];
            int len = right - left + 1;
            if (total % len != 0) continue;
            int avg = total / len;
            if (avg <= 1000 && freq[avg]) {
                result++;
            }
        }
    }
    cout << result << endl;
    return 0;
}

第三题:一成不变

在无限大的二维网格上,N 头奶牛初始位于不同位置,分别朝北或朝东移动。每头奶牛每小时吃掉当前格子的草后前进一格。如果目标格子的草已被吃掉(非同时到达),则停止。求每头奶牛吃到的草的数量,或输出 "Infinity"。

关键在于理解阻挡关系:朝东的奶牛只会被朝北的奶牛阻挡,反之亦然。直接模拟会超时,需要利用几何分析。

核心思路:将朝东的奶牛按 y 坐标排序,朝北的奶牛按 x 坐标排序。对于每一对可能相交的东向牛和北向牛,判断它们的路径交点。若东向牛先到达交点,则它能阻挡北向牛;若北向牛先到达,则它能阻挡东向牛。同时到达则互相不阻挡。需要记录每头牛被阻挡的最早时间(即吃到的草数)。

#include <bits/stdc++.h>
using namespace std;

struct Cow {
    int x, y, idx, eaten;
    Cow(int _x = 0, int _y = 0, int _i = 0) : x(_x), y(_y), idx(_i), eaten(0) {}
};

Cow east[55], north[55];
int finalAns[55];
int cntE, cntN, total;

bool cmpEast(Cow a, Cow b) {
    return a.y < b.y;
}

bool cmpNorth(Cow a, Cow b) {
    return a.x < b.x;
}

int main() {
    freopen("stuct.in", "r", stdin);
    freopen("stuct.out", "w", stdout);
    cin >> total;
    for (int i = 1; i <= total; i++) {
        char dir;
        int px, py;
        cin >> dir >> px >> py;
        if (dir == 'E') {
            east[++cntE] = Cow(px, py, i);
        } else {
            north[++cntN] = Cow(px, py, i);
        }
    }
    sort(east + 1, east + cntE + 1, cmpEast);
    sort(north + 1, north + cntN + 1, cmpNorth);
    
    for (int i = 1; i <= cntE; i++) {
        for (int j = 1; j <= cntN; j++) {
            if (east[i].y < north[j].y || east[i].x > north[j].x) continue;
            int distE = north[j].x - east[i].x;
            int distN = east[i].y - north[j].y;
            if (distE == distN) continue; // 同时到达,互不阻挡
            
            if (distN > distE) {
                // 北向牛先被阻挡
                if (north[j].eaten == 0 || distN < north[j].eaten) {
                    north[j].eaten = distN;
                }
            } else {
                // 东向牛先被阻挡
                if (east[i].eaten == 0 || distE < east[i].eaten) {
                    east[i].eaten = distE;
                }
            }
        }
    }
    
    for (int i = 1; i <= cntE; i++) {
        if (east[i].eaten == 0) {
            finalAns[east[i].idx] = -1;
        } else {
            finalAns[east[i].idx] = east[i].eaten;
        }
    }
    for (int i = 1; i <= cntN; i++) {
        if (north[i].eaten == 0) {
            finalAns[north[i].idx] = -1;
        } else {
            finalAns[north[i].idx] = north[i].eaten;
        }
    }
    
    for (int i = 1; i <= total; i++) {
        if (finalAns[i] == -1) {
            cout << "Infinity" << endl;
        } else {
            cout << finalAns[i] << endl;
        }
    }
    return 0;
}

注意上述代码需要修正:实际阻挡逻辑需考虑已被其他牛阻挡的情况,即只有当当前牛到达交点的时间严格小于该牛已被记录的停止时间时,才更新。完整的正确实现应在交叉判断时,检查两头牛是否都还未被更早阻挡。

返回列表

上一篇:Shiro 使用 INI 配置文件进行安全设置

没有最新的文章了...

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。