2015年上海现场赛重现 (A几何, K暴力搜索)

A:

题目链接 :https://vjudge.net/contest/250823#problem/A

参考 : https://www.cnblogs.com/helenawang/p/5465481.html

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

const double eps = 1e-8;

int cmp(double x){
    return x < -eps ? -1 : (x>eps);
}

double pow2(double x){
    return x * x;
}

double mySqrt(double x){
    return sqrt(max((double)0, x));
}

struct Vec
{
    double x, y;
    Vec(){}
    Vec(double xx, double yy):x(xx), y(yy){}

    Vec& operator=(const Vec& v){
        x = v.x;
        y = v.y;
        return *this;
    }

    double norm(){
        return sqrt(pow2(x) + pow2(y));
    }
    //返回单位向量
    Vec unit(){
        return Vec(x, y) / norm();
    }
    //判等
    friend bool operator==(const Vec& v1, const Vec& v2){
        return cmp(v1.x - v2.x)==0 && cmp(v1.y - v2.y)==0;
    }

    //+, -, 数乘
    friend Vec operator+(const Vec& v1, const Vec& v2){
        return Vec(v1.x + v2.x, v1.y + v2.y);
    }
    friend Vec operator-(const Vec& v1, const Vec& v2){
        return Vec(v1.x - v2.x, v1.y - v2.y);
    }
    friend Vec operator*(const Vec& v, const double c){
        return Vec(c*v.x, c*v.y);
    }
    friend Vec operator*(const double c, const Vec& v){
        return Vec(c*v.x, c*v.y);
    }
    friend Vec operator/(const Vec& v, const double c){
        return Vec(v.x/c, v.y/c);
    }
};

int T;
int ans;
Vec O, A, V, B, C, B1;
int R;

//点乘
double dot(const Vec v1, const Vec v2){
    return v1.x*v2.x + v1.y*v2.y;
}
//叉乘的模长
double product(const Vec v1, const Vec v2){
    return v1.x*v2.y - v1.y*v2.x;
}

//点p到直线v1,v2的投影
Vec project(Vec& v1, Vec& v2, Vec& p){
    Vec v = v2 - v1;
    return v1 + v * dot(v, p-v1) / dot(v, v);
}
//点p关于直线v1,v2的对称点
Vec mirrorPoint(Vec& v1, Vec& v2, Vec& p){
    Vec c = project(v1, v2, p);
    //printf("project: %lf, %lf\n", c.x, c.y);
    return (double)2*c - p;
}

//判断点p是否在线段v1,v2上
bool onSeg(Vec& v1, Vec& v2, Vec& p){
    if(cmp(product(p-v1, v2-v1))==0 && cmp(dot(p-v1, p-v2))<=0)
        return true;
    return false;
}

bool calc_C(){
    //将AC表示为关于t的参数方程
    //则与圆的方程联立得到关于t的一元二次方程, a,b,c为一般式的三个系数
    double a = pow2(V.x) + pow2(V.y);
    double b = 2*V.x*(A.x - O.x) + 2*V.y*(A.y - O.y);
    double c = pow2(A.x - O.x) + pow2(A.y - O.y) - pow2(R);
    double delta = pow2(b) - 4*a*c;
    if(cmp(delta) <= 0) return false;
    else{
        double t1 = (-b - mySqrt(delta))/(2*a);
        double t2 = (-b + mySqrt(delta))/(2*a);
        double t;
        if(cmp(t1) >= 0) t = t1;
        if(cmp(t2) >= 0 && t2 < t1) t = t2;//取较小的那个,即为离A近的那个交点
        C.x = A.x + V.x*t;
        C.y = A.y + V.y*t;
        return true; //有交点
    }
}

int main()
{
    freopen("5572.txt", "r", stdin);
    scanf("%d", &T);
    for(int ca = 1; ca <= T; ca++){
        scanf("%lf%lf%d", &O.x, &O.y, &R);
        scanf("%lf%lf%lf%lf", &A.x, &A.y, &V.x, &V.y);
        scanf("%lf%lf", &B.x, &B.y);
        if(calc_C()){
            if(onSeg(A, C, B)) ans = 1;
            else{
                //printf("has intersection (%lf, %lf)\n", C.x, C.y);
                Vec A1 = mirrorPoint(O, C, A);
                  // printf("A: %lf, %lf\n", A.x, A.y);
                  // printf("A1: %lf, %lf\n", A1.x, A1.y);
                //printf("B1 (%lf, %lf)\n", B1.x, B1.y);
                if(A==A1){
                    Vec u = B - O;
                    Vec v = C - O;
                    // printf("OB: %lf %lf\n", u.unit().x, u.unit().y);
                    // printf("OC: %lf %lf\n", v.unit().x, v.unit().y);
                    if(u.unit() == v.unit()){
                        ans = 1;
                    }else ans = 0;
                }else {
                    Vec u = B - C;
                    Vec v = A1 - C;
                    if(u.unit() == v.unit()){
                        ans = 1;
                    }
                    else ans = 0;
                }
            }
        }else{//运动方向不变,则AB与V同向才可碰到B
            //printf("no intersection\n");
            Vec temp = B - A;
            if(temp.unit() == V.unit())
                ans = 1;
            else ans = 0;
        }
        printf("Case #%d: %s\n", ca, ans ? "Yes" : "No");
    }
    return 0;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const double PI = acos(-1.0);
const double eps = 1e-8;

int sgn(double x)
{
    if(fabs(x) <= eps) return 0;
    if(x <0 )return -1;
    else return 1;
}

struct Point{
    double x,y;
    Point(){}
    Point(double _x ,double _y)
    {
        x = _x, y = _y;
    }

    // 利用函数重载求各种点之间的运算
    Point operator +(const Point &b)const{
        return Point(x+b.x, y+b.y);
    }
    Point operator -(const Point &b)const{
        return Point(x-b.x, y-b.y);
    }
    double operator *(const Point &b)const{
        return (x*b.x + y*b.y);
    }
    double operator ^(const Point &b)const{
        return (x*b.y - y*b.x);
    }
    Point operator *(const double &k)const{
        return Point(x*k, y*k);
    }
    Point operator /(const double &k)const{
        return Point(x/k, y/k);
    }
    // 求点绕远点逆时针旋转后的坐标, 角度A是弧度制
    void transXY(double A)
    {
        x = x*cos(A) - y*sin(A);
        y = x*sin(A) + y*cos(A);
    }
    double len(){return hypot(x,y);}  // hypot用于求平方和再开方
    double len2() {return x*x + y*y;}
    // 求两点之间的距离
    double distance(Point p){return hypot(x-p.x ,y-p.y );}

    Point trunc(double r) {
        double l = len();
        if(!sgn(l)) return *this;
        r /= l;
        return Point (x*r, y*r);
    }
};

struct Line {
    Point s,e;
    Line(){}
    Line(Point _s,Point _e)  {
       s = _s;e = _e;
    }
    double length(){ return s.distance(e);}
    pair<int,Point> operator &(const Line &b)const {
        Point res = s;
        if(sgn((s-e)^(b.s-b.e)) == 0) {
            if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res);
            else return make_pair(1,res);
        }
        double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
        res.x += (e.x-s.x)*t;
        res.y += (e.y-s.y)*t;
        return make_pair(2,res);
    }
    int relation(Point p) {
        int c = sgn((p - s) ^ (e - s));
        if(c < 0) return 1;
        else if(c > 0) return 2;
        else return 3;
    }
    double disPointtoline(Point p) { return fabs((p-s)^(e-s))/length();}
    double disPointtoseg(Point p) {
        if(sgn((p - s) * (e - s)) < 0 || sgn((p - e) * (s - e)) < 0)
        return min(p.distance(s), p.distance(e));
        return disPointtoline(p);
    }
    Point lineprog(Point p) { return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));}
    Point symmetryPoint(Point p) {
        Point q = lineprog(p);
        return Point(2*q.x-p.x, 2*q.y-p.y);
    }
};

struct Circle {
    Point p;
    double r;
    int relationline(Line v) {
        double dst = v.disPointtoline(p);
        if(sgn(dst-r) < 0) return 2;
        else if(sgn(dst-r) == 0) return 1;
        return 0;
    }
    int Pointcrossline(Line v, Point &p1, Point &p2) {
        if(!(*this).relationline(v)) return 0;
        Point a = v.lineprog(p); double d = v.disPointtoline(p);
        d = sqrt(r*r-d*d);
        if(sgn(d) == 0) {p1 = a; p2 = a; return 1;}
        p1 = a + (v.e - v.s).trunc(d);
        p2 = a - (v.e - v.s).trunc(d);
        return 2;
    }
    int relationseg(Line v) {
         double dst = v.disPointtoseg(p);
        if(sgn(dst - r) < 0) return 2;
        else if(sgn(dst - r) == 0) return 1;
        else return 0;
    }
};

int main() {
    int t;
    scanf("%d", &t);
    Circle c;
    Point a, v, b;
    for(int o = 1; o <= t; o++) {
        printf("Case #%d: ", o);
        scanf("%lf %lf %lf", &c.p.x, &c.p.y, &c.r);
        scanf("%lf %lf %lf %lf", &a.x, &a.y, &v.x, &v.y);
        scanf("%lf %lf", &b.x, &b.y);
        Line ab = Line(a, b);
        Point av = a + v;
        Line l = Line(a, av);
        int flag = 0;
        if(l.relation(b) == 3 && sgn((b-a)*(av-a)) > 0 && c.relationseg(ab) <= 1) flag = 1;
        else {
            Point p1, p2;
            if(c.Pointcrossline(l, p1, p2) == 2) {
                Point m = sgn(a.distance(p1) - a.distance(p2)) < 0 ? p1 : p2;
                Line f(c.p, m);
                Point q = f.symmetryPoint(a);
                Line tmp(m, q);
                if(tmp.relation(b) == 3 && sgn(((b-m)*(q-m)))>0) flag = 1;
            }
        }
        puts(flag?"Yes":"No");
    }
    return 0;
}

K:

题目链接 : https://vjudge.net/contest/250823#problem/K

输出没有加Case狂wa, 坑爹啊;

#include<iostream>
#include<cstdio>
#include<vector>

using namespace std;
#define ll long long
const int maxn = 100010;

ll cal(ll a)  // 计算平方
{
    return a*a;
}

vector<int > v;  // 用于存每一个子序列的长度

int main()
{
    int t;
    cin >> t;
    int j =0;
    while(j++ < t)
    {
        string s;
        cin >> s;
        v.clear();  // 清空
        v.push_back(0);  // 在数组首加入0
        int last = s[0];
        ll ans = 0, cnt = 1;
        for(int i = 1; i < s.size(); i++)  // 从第二个字符开始遍历
        {
            if(s[i] == s[i-1])  // 相等则长度加一
            {
                cnt++;
            }
            else {
                ans += cal(cnt);    // 加上该子串对结果的贡献,先不考虑更改字符
                v.push_back(cnt);  // 如果不等则把cnt 记录到数组
                cnt =1;
                last = s[i];
            }

        }
        v.push_back(cnt);
        ans += cal(cnt);
       // cout << ans << endl;
        v.push_back(0);  // 在数组尾加入0
       // for(int i = 0; i < v.size(); i++)
           // cout << v[i] << " ";
        ll ans2 = ans;
        for(int i = 1; i < v.size()-1; i++)
        {
            ll tmp, tmp2;
            if(v[i] == 1)
            {
                tmp = ans+cal(v[i-1]+v[i+1]+1)-1-cal(v[i-1])-cal(v[i+1]);
                ans2 = max(ans2, tmp);
            }
            else
            {
                tmp2 = ans+cal(v[i-1]+1)+cal(v[i]-1)-cal(v[i])-cal(v[i-1]);
                ans2 = max(ans2, tmp2);
            }
        }
        printf("Case #%d: %lld\n", j, ans2);
    }

}

原文地址:https://www.cnblogs.com/mrh-acmer/p/9557857.html

时间: 2024-11-09 02:47:37

2015年上海现场赛重现 (A几何, K暴力搜索)的相关文章

2018ICPC青岛现场赛 重现训练

先贴代码,以及简要题解. 和一个队友下午双排打了一下,队友光速签到,我签的J被嫌弃写得慢以及演员...然后我秒出了E了思路然而难以置信这么简单的思路当时才过了十几个,于是发现D.F不是太好做.最后交了13发E才过,中间爆ll.memset超时..赛后补了F. 只贴我写的三个题. J: ZOJ 4067 题解:把所有0拿掉后贪心拿完前面的,然后再加上后面的最小值-1.改了三次在基佬紫帮助下才写对. #include<cstdio> #include<iostream> #includ

HDU5572 2015上海现场赛A题1001

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<map> 6 #include<set> 7 #include<cmath> 8 using namespace std; 9 typedef long long LL; 10 const double eps = 1e-8; 11 int sgn

ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem

题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射. 学到了向量模板,写法简洁. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define clc(a,b) sizeof(a,b,sizeof(a)) 6

[2016CCPC]长春现场赛重现

1002.公式,手算一下就能找到两个式子的关系,迭代一下就行. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 9; 5 int a[maxn], b[maxn]; 6 int n, p, q; 7 8 int gcd(int x, int y) { 9 return y == 0 ? x : gcd(y, x%y); 10 } 11 12 int main() { 13 //freopen(&quo

HDU 5245 Joyful (2015年上海大都赛J题,概率)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5245 题意: 给定一个n*m的矩形,由n*m个格子组成,我们可以选k次,每次可以选择的两个格子 这两个格子作为矩形的对角线可以确定一个矩形,这个矩形里的所有小格子都会被覆 盖,求k次后,被覆盖的格子的个数的期望. 分析: 棋盘被覆盖的格子数的期望 = 每个格子被覆盖的概率的和. 每次选择的方案有n*m*n*m种. 格子坐标为(i,j)被覆盖的方案数为: tot = 2*(2*(i*j*(n-i+1)

ACM/ICPC2015上海现场赛B题题解

给你一棵完全二叉树,初始能量为0,根节点编号为1(也就是说最左边那条路上节点的编号分别是2^0,2^1,2^2…2^(h-1)).从根节点开始往下走k-1步,走到每个节点选择加上或减去这个节点的编号,问走完这k个节点时能量恰好为n的方案.Special Judge. 在队友的提醒下(TAT我真是讨厌鹰语)看明白了数据范围,很明显是一个考二进制性质的题.于是一上手我先把样例改成了走最左路线的情况.样例出的蛮良心,一个奇数一个偶数,刚好对应两条路线:一直走左儿子或者走k-2个左儿子最后一个走右儿子.

2014 ACM 上海现场赛B,I,J &amp;&amp; UVALive7146 7147 7139

2014最难赛区 7146 贪心这道题是考验STL的. 我们按照一个顺序排序(我方攻击力升序,敌方防御力升序), 此时因为要全部歼灭,优先考虑如何干掉敌方防御力最高的,此时将所有攻击力比它高的我方都放入multiset中维护,然后选择一个"最合适"的匹配(如果有我方防御力大于此时敌方攻击力的元素就使用,若没有就牺牲.首要任务是全部歼灭,此时能够消灭这个敌方的人都已经在multiset中了,若能够不牺牲却让其牺牲是不必要的,因为后面的元素已经保证能够歼灭后面的敌方) #include&l

2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 A Fruit Ninja

传送门 题解:给你一堆点问你能不能找出一条直线,使其穿过的点大于n*x. 题解:想起某道CF题目,给你一堆点问你能不能找出两条直线使其穿过所有的点.当时就是在一定时限内随机找了两个点,再枚举每个点是否满足,如果超过该时限仍然不满足则直接返回no.这题也是一样的做法,直接随机两个点,再枚举过去.因为x为0.1到0.9,所以如果所给数据满足条件,那么它有极大概率能够跑出结果.4发只有一次超时 #include<bits/stdc++.h> //CLOCKS_PER_SEC #define se s

2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛-K-Matrix Multiplication(矩阵乘法)

题目描述 In mathematics, matrix multiplication or matrix product is a binary operation that produces a matrix from two matrices with entries in a field, or, more generally, in a ring or even a semiring. The matrix product is designed for representing the