上海现场赛重现 (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 国际大学生程序设计竞赛上海大都会赛重现赛-K-Matrix Multiplication(矩阵乘法)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 A Fruit Ninja
HDU 5926 Mr. Frog’s Game(连连看,暴力)——2016CCPC东北地区大学生程序设计竞赛 - 重现赛