HDU.4617 Weapon

本文介绍了一种计算两个无限长圆柱体之间最短距离的方法。通过判断圆柱中轴线是否平行来选择合适的距离计算公式,平行时使用点到直线的距离,异面时使用两直线间的最小距离。

【题意】N<=30无限长圆柱体,求任意两个圆柱体之间的最短距离。

【解题方法】圆柱之间的距离就是中轴线的距离,平行的话很简单,异面的话不会算,记录一下模板吧。

【AC code】


<nobr>#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
int sgn(double x)
{
    return x<-eps?-1:x>eps;
}
struct node{
    double x,y,z;
    void read()
    {
        scanf("%lf%lf%lf",&x,&y,&z);
    }
    node operator+(const node &p){
        return {x+p.x,y+p.y,z+p.z};
    }
    node operator-(const node &p){
        return {x-p.x,y-p.y,z-p.z};
    }
    double operator*(const node &p){
        return x*p.x+y*p.y+z*p.z;
    }
    node operator^(const node &p){
        return {y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x};
    }
    double length()
    {
        return sqrt(*this **this);
    }
}p[33][3];
using point=node;
double r[33];//圆柱的半径
point normal[33];//计算法向量
bool pingxing(point a,point b)
{
    return sgn((a^b).length())<=0;
}
double pointtoline(point a,point b,point c)
{
    point fa=a-b;
    return (fa^c).length()/c.length();
}
double linetoline(point a,point b,point c,point d)
{
    point fa=b^d;
    return abs((a-c)*fa)/fa.length();
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++){
            for(int j=0; j<3; j++){
                p[i][j].read();
            }
            r[i]=(p[i][1]-p[i][0]).length();
            normal[i]=(p[i][1]-p[i][0])^(p[i][2]-p[i][0]);
        }
        double ans=1e18;
        for(int i=1; i<=n; i++){
            for(int j=i+1; j<=n; j++){
                double d=0;
                if(pingxing(normal[i],normal[j])) d=pointtoline(p[i][0],p[j][0],normal[j]);
                else d=linetoline(p[i][0],normal[i],p[j][0],normal[j]);
                ans=min(ans,max(0.00,d-r[i]-r[j]));
            }
        }
        if(sgn(ans)==0){
            puts("Lucky");
        }else{
            printf("%.2f\n",ans);
        }
    }
}
第五届广西省大学生程序设计竞赛K Kirby's challenge(AC代码) 分数 300 作者 Colin 单位 杭州电子科技大学 Description Recently, Colin bought a Switch for Eva. And they are playing "Kirby and the Forgotten Land". In a challenge mission, Kirby is in a 4×n grid. The row of it is numbered from 1 to 4, and the column of it is numbered from 1 to n. There are many keys in this grid. Let a x,y ​ represent the status of cell (x,y). If a x,y ​ =1, there is a key in (x,y). If a x,y ​ =0, there is no key in (x,y). Kirby starts at (1,1), and should reach (4,n). Moreover, Kirby must collect all the keys in the grid to open the door in (4,n). Kirby will collect the key at (x,y) when Kirby reach (x,y). Of course, Kirby will collect the key at (1,1) at the beginning. In a second, Kirby can move from (x,y) to (x+1,y),(x,y+1),(x−1,y). Or Kirby can stay at (x,y) and throw a returnable flying weapon(boomerang) to collect keys in the flying path. Kirby has two ways to throw the weapon. As the picture shows: image-20220604213457062.png The flying path is represented as the grey cells, so keys in the grey cells can be collected by the weapon. In a second, Kirby can only choose one way to throw the weapon, but Kirby can throw the weapon multiple times at (x,y) if necessary. Notice: Kirby can't get off the grid, but the weapon can fly outside the grid and keep the flying path. Please write a program to help Colin and Eva find the shortest time to complete the challenge mission, so that they can get more rewards. Input The first line contains one integer n (1≤n≤100). In the next 4 lines, the x-th line contains n integers a x,1 ​ ,a x,2 ​ ,⋯,a x,n ​ (0≤a x,y ​ ≤1). Output Print one integer representing the minimum number of seconds required to complete the challenge mission. Sample input 1 5 1 1 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 output 1 8 The best solution is: Spend 1 second to throw the weapon in the second way at (1,1), and spend 7 seconds to reach (4,5). 代码长度限制 16 KB 时间限制 1000 ms 内存限制 512 MB 栈限制 131072 KB
08-09
HDU 6259 是一道与回文子串相关的编程题目,要求统计特定条件下回文子串的数量。题目通常涉及字符串操作、动态规划或 Manacher 算法等技术。 ### 解题思路 题目核心在于识别并统计满足特定条件的回文子串。通常的解题方法包括: - **暴力枚举**:适用于小规模输入,时间复杂度为 $ O(n^2) $。 - **动态规划**:使用二维数组 `dp[i][j]` 表示从索引 `i` 到 `j` 的子串是否为回文。 - **Manacher 算法**:线性时间复杂度 $ O(n) $ 的高效算法,适用于大规模输入。 ### 示例代码 以下是一个使用动态规划方法统计所有回文子串的示例代码: ```cpp #include <iostream> #include <vector> #include <string> using namespace std; int countPalindromicSubstrings(string s) { int n = s.size(); vector<vector<bool>> dp(n, vector<bool>(n, false)); int count = 0; // 单个字符的回文 for (int i = 0; i < n; ++i) { dp[i][i] = true; ++count; } // 两个字符的回文 for (int i = 0; i < n - 1; ++i) { if (s[i] == s[i + 1]) { dp[i][i + 1] = true; ++count; } } // 更长的回文子串 for (int length = 3; length <= n; ++length) { for (int i = 0; i <= n - length; ++i) { int j = i + length - 1; if (s[i] == s[j] && dp[i + 1][j - 1]) { dp[i][j] = true; ++count; } } } return count; } int main() { string s; cin >> s; cout << countPalindromicSubstrings(s) << endl; return 0; } ``` ### 时间与空间复杂度分析 - **动态规划**:时间复杂度为 $ O(n^2) $,空间复杂度为 $ O(n^2) $。 - **Manacher 算法**:时间复杂度为 $ O(n) $,空间复杂度为 $ O(n) $。 ### 优化建议 对于大规模字符串(如长度超过 $ 10^5 $),应优先使用 Manacher 算法以提升效率。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值