UVA 11526 - H(n)

本文探讨了一种优化算法在解决数学问题上的应用,通过实例展示了如何通过算法优化来简化求解过程,使得原本复杂的计算变得更为直观和高效。

这个题 很久之前做数学的时候 就做过了。 但是当时没做出来。 水平很有限。 


现在再看这个题 就有点简单了。  就是 求 每个数 有几个 然后乘起来就好。


这个题重在优化。 一开始 还在找规律。 结果没找到。 就去优化了。


比如 10 的时候   10 5 3 2 2 1 1 1 1 1   就是 一个 10  一个 5 一个3 两个2  5个 1  实现如下。


#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
using namespace std;
#define ll long long
typedef unsigned long long ull;
#define maxn 1000+100
#define INF 1<<30
int main (){
    int num;
    scanf("%d",&num);
    while(num--){
        ll n;
        scanf("%lld",&n);
        ll sum = 0;
        for(ll i = 2; i <= n; i++){
            ll tem = n / i;
            ll z = n / tem;
            sum += (z - i + 1)*tem;
            i = n / tem;
        }
        if(n >= 0)
            sum += n;
        printf("%lld\n",sum);
    }
    return 0;
}


UVA10100 - "Herding Frosh" 是一个与几何和模拟相关的编程问题。题目大意是:在平面上有若干个事件点(代表frosh的行为),需要将这些点用一条绳子围起来,使得绳子的长度最短。如果有多个最短长度的解,则选择字典序最小的解。 ### 问题分析 该问题本质上是计算几何中的最小周长凸包问题,但需要注意的是,当点数小于3时,结果并非简单的线段或三角形,而是根据题目描述进行特殊处理。此外,输出要求包括点的顺序(按字典序排列),这也增加了问题的复杂性。 解题思路主要包括以下几个步骤: 1. **输入处理**:读取输入的点坐标,注意可能存在多个测试用例。 2. **凸包计算**:使用凸包算法(如Graham扫描法或Andrew算法)构造最小包围所有点的凸多边形。 3. **周长计算**:计算凸包的周长。 4. **字典序比较**:在多个解中选择字典序最小的点序列。 ### 算法实现要点 - 使用Andrew算法可以高效地构造凸包,时间复杂度为 $ O(n \log n) $。 - 点的排序是关键,需按照x坐标为主、y坐标为辅进行排序。 - 凸包构造时,需分别处理上凸包和下凸包。 - 对于点数小于3的情况,需要单独处理,以避免构造凸包时出现错误。 ### 示例代码 下面是一个基于Andrew算法的实现示例: ```cpp #include <bits/stdc++.h> using namespace std; struct Point { int x, y; bool operator < (const Point &p) const { return x == p.x ? y < p.y : x < p.x; } }; int cross(Point o, Point a, Point b) { return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x); } vector<Point> convex_hull(vector<Point> pts) { if (pts.size() <= 1) return pts; sort(pts.begin(), pts.end()); vector<Point> lb, ub; for (int i = 0; i < pts.size(); ++i) { while (lb.size() >= 2 && cross(lb[lb.size()-2], lb.back(), pts[i]) <= 0) lb.pop_back(); lb.push_back(pts[i]); } for (int i = pts.size()-1; i >= 0; --i) { while (ub.size() >= 2 && cross(ub[ub.size()-2], ub.back(), pts[i]) <= 0) ub.pop_back(); ub.push_back(pts[i]); } lb.pop_back(); ub.pop_back(); for (auto p : ub) lb.push_back(p); return lb; } double dist(Point a, Point b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } double convex_perimeter(vector<Point> ch) { double res = 0; for (int i = 0; i < ch.size()-1; ++i) res += dist(ch[i], ch[i+1]); if (ch.size() > 1) res += dist(ch.back(), ch[0]); return res; } ``` ### 输出格式处理 最终输出需要包括凸包的周长(保留两位小数)以及凸包的顶点序列,顶点顺序需按字典序排列。若存在多个相同长度的解,选择字典序最小的那个。 ### 注意事项 - 需要处理浮点数精度问题。 - 点的重复可能导致凸包构造失败,应提前去重。 - 输出格式需严格按照题目要求处理,包括空格、换行等细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值