icpc2013长沙区域赛

本文详细介绍了2013年ICPC长沙区域赛的多个编程题目,包括Alice's Print Service、Collision、Graph Reconstruction、Skycity、LIKE vs CANDLE、Josephina and RPG和Pocket Cube等,提供了每道题目的题意、解题思路和代码实现。
摘要由CSDN通过智能技术生成

icpc2013长沙区域赛

A.Alice’s Print Service

题意: 现在你要打印一些东西,比如需要99张纸,打印100张以下时话费10元每张,100张及100张以上时需要5元每张,此时你可以选择打印100张,使得花费更小。现给一个数字n,表示n个区间段,然后有s1,p1,s2,p2…sn,pn,表示打印纸张大于等于s1而小于s2时,每张纸话费p1元,现有m个询问,问每次给你x张纸,所需的最小花费是多少。

题解: 先倒着 O ( n ) O(n) O(n)预处理一遍打印多少纸张的最小划分是多少,然后每次询问二分去找答案即可

代码:

#include <bits/stdc++.h>

using namespace std;

#define MAXN 100100

long long s[MAXN], p[MAXN];
long long minm[MAXN];
int main() {
   
    long long n, m, i, j;
    long long t;
    long long x, ans;
    scanf("%lld", &t);
    while (t--) {
   
        scanf("%lld%lld", &n, &m);
        for (i = 0; i < n; i++) {
   
            scanf("%lld%lld", &s[i], &p[i]);
        }
        minm[n - 1] = s[n - 1] * p[n - 1];
        for (i = n - 2; i >= 0; i--) {
   
            long long tt = s[i] * p[i];
            minm[i] = min(tt, minm[i + 1]);
        }
        for (i = 0; i < m; i++) {
   
            scanf("%lld", &x);
            int pp = upper_bound(s, s + n, x) - s;
            pp--;
            if (pp == n - 1) {
   
                ans = x * p[n - 1];
            } else
                ans = min(minm[pp + 1], x * p[pp]);
            printf("%lld\n", ans);
        }
    }
    return 0;
}

C.Collision

题意: 给出一个半径为R的大圆,这个圆里面有一个同心圆model,现在向这个model发射一枚硬币(给出速度vx,vy),碰到model会反射,问硬币在大圆内运行的时间(保证硬币的初始位置在圆外)

题解: 首先判断是否是向大圆方向射去,也就是点到圆心的向量和速度向量的夹角是否小于90度,不小于90度则肯定不会相交,判断夹角小于90度可以用点积大于0来求。然后判断运行轨迹是否能碰到model,这里用点到直线距离来求即可,如果原点到直线的距离小于等于r+Rm,那么肯定不反射,直接利用勾股定理求时长即可。最后是反射的情况:

rt77FS.png

利用两次勾股定理算出x,因为是对称的,直接乘2即可

代码:

#include <bits/stdc++.h>

using namespace std;

// 计算几何模板
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
// 和0做比较
int sgn(double x) {
   
    if (fabs(x) < eps) return 0;  // =0
    if (x < 0)
        return -1;  // < 0
    else
        return 1;  // > 0
}
// 计算x的平方
inline double sqr(double x) {
    return x * x; }
struct Point {
   
    double x, y;
    Point() {
   }
    Point(double _x, double _y) {
   
        x = _x;
        y = _y;
    }
    void input() {
    scanf("%lf%lf", &x, &y); }
    void output() {
    printf("%.2f %.2f\n", x, y); }
    bool operator==(Point b) const {
   
        return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
    }
    bool operator<(Point b) const {
   
        return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
    }
    Point operator-(const Point &b) const {
    return Point(x - b.x, y - b.y); }
    //叉积
    double operator^(const Point &b) const {
    return x * b.y - y * b.x; }
    //点积
    double operator*(const Point &b) const {
    return x * b.x + y * b.y; }
    //返回向量长度
    double len() {
   
        // hypot(x, y), 即sqrt(x * x + y * y)
        return hypot(x, y);  //库函数
    }
    //返回长度的平方
    double len2() {
    return x * x + y * y; }
    //返回两点的距离
    double dist(Point p) {
    return hypot(x - p.x, y - p.y); }
    Point operator+(const Point &b) const {
    return Point(x + b.x, y + b.y); }
    Point operator*(const double &k) const {
    return Point(x * k, y * k); }
    Point operator/(const double &k) const {
    return Point(x / k, y / k); }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值