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

Posted mrh-acmer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上海现场赛重现 (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
", 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)
", C.x, C.y);
                Vec A1 = mirrorPoint(O, C, A);
                  // printf("A: %lf, %lf
", A.x, A.y);
                  // printf("A1: %lf, %lf
", A1.x, A1.y);
                //printf("B1 (%lf, %lf)
", B1.x, B1.y);
                if(A==A1){
                    Vec u = B - O;
                    Vec v = C - O;
                    // printf("OB: %lf %lf
", u.unit().x, u.unit().y);
                    // printf("OC: %lf %lf
", 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
");
            Vec temp = B - A;
            if(temp.unit() == V.unit())
                ans = 1;
            else ans = 0;
        }
        printf("Case #%d: %s
", 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
", j, ans2);
    }

}

 

以上是关于上海现场赛重现 (A几何, K暴力搜索)的主要内容,如果未能解决你的问题,请参考以下文章

2017.11.11 ACM-ICPC2017亚洲区域赛(沈阳)重现赛 7/13 Rank10

2018 ACM 国际大学生程序设计竞赛上海大都会赛

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

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

2018ICPC青岛现场赛 重现训练

HDU 5926 Mr. Frog’s Game(连连看,暴力)——2016CCPC东北地区大学生程序设计竞赛 - 重现赛