2018ACM 牛客网多校赛 模板收集(第三场)

什么!!!你没有板子T^T,我也没有,但是我赛后在别人代码里扒了一个。 —— 阿狸是狐狸啦

J 作者:阿狸是狐狸啦
链接:https://www.nowcoder.com/discuss/88447?type=101&order=0&pos=6&page=0
来源:牛客网

给出一个多边形(多边形的点按照逆时针或者顺时针给出),m次查询,每次给出x,y,p,q。以x,y为圆心的的圆占了多边形总面积的(q-p)/q。问你这个圆的半径是多少。
知道题意后就简单了,二分一下半径,求一下面积是否满足条件,eps调小点,防止被卡精度。套一套多边形和圆面积交的模板就可以了。

代码贴在最后了。

E 字符串哈希模板
作者:tokitsukaze
链接:https://www.nowcoder.com/discuss/88498?type=101
来源:牛客网

题意:
给一个字符串,复制前n-1个字符后,问有多少种长度n的子串,分类后按字典序输出下标。

这里写图片描述

上图是以样例abab来进行解释的

题解:
复制一遍字符串,然后预处理hash表。之后for每个起始位置,可以在O(1)的时间获取子串的hash值,然后扔进map分类即可。对于这种写法字典序不需要特殊处理。
这个题卡常…有两个点要注意一下。
1.mod取1e9+7会冲突(过了62.5%的数据),而且每次%常数很大,会tle,这里选用了ull(自动%2^64)。
2.要用unordered_map,不然会tle。

I 作者:tokitsukaze
链接:https://www.nowcoder.com/discuss/88512?type=101&order=0&pos=3&page=0
来源:牛客网

http://tokitsukaze.live/2018/07/27/2018niuke3.I/

题意:
给一个三角形,让你在三角形内随机选n个点,问这n个点在凸包上的期望是多少。

题解:
显然三角形长什么样,对答案没有影响。
注意到n<=10,所以做法就是:在三角形内随机n个点,求凸包,然后求多少个点在凸包上。随机次数越多,答案是准确率越高。最后打个表交上去就行了。

code I:

作者:tokitsukaze
链接:https://www.nowcoder.com/discuss/88512?type=101&order=0&pos=3&page=0
来源:牛客网

#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define mem(a,b) memset((a),(b),sizeof(a))
#define MP make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define all(x) x.begin(),x.end()
using namespace __gnu_cxx;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef vector<int> VI;
typedef vector<ll> VL;
const int INF=0x3f3f3f3f;
const ll LLINF=0x3f3f3f3f3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-6;
const int MAX=1e5+10;
const ll mod=1e9+7;
/*********************************  head  *********************************/
int sgn(double x)
{  
    if(fabs(x)<eps) return 0;
    else return x>0?1:-1;  
}
struct Point
{  
    double x,y;
    Point(){}
    Point(double a,double b)
    {
        x=a;
        y=b;
    }
    void input()
    {
        scanf("%lf%lf",&x,&y);
    }
};
typedef Point Vector;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}  
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}  
Vector operator *(Vector a,double p){return Vector(a.x*p,a.y*p);}  
Vector operator /(Vector a,double p){return Vector(a.x/p,a.y/p);}
bool operator <(Point a,Point b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool operator ==(Point a,Point b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}
double cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
vector<Point> graham(vector<Point> p)
{  
    int n,m,k,i;
    sort(p.begin(),p.end());
    p.erase(unique(p.begin(),p.end()),p.end());
    n=p.size();
    m=0;
    vector<Point> res(n+1);  
    for(i=0;i<n;i++)
    {  
        while(m>1&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<=0) m--;  
        res[m++]=p[i];  
    }  
    k=m;  
    for(i=n-2;i>=0;i--)
    {  
        while(m>k&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<=0) m--;  
        res[m++]=p[i];  
    }  
    if(n>1) m--;  
    res.resize(m);
    return res;
}
Point randp()
{
    while(1)
    {
        Point p(rand(),rand());
        if(p.x+p.y<=32766) return p;
    }
    return Point(0,0);
}
void gao()
{
    srand(time(0));
    for(int i=4;i<=10;i++)
    {
        int t=20000000;
        double ans=0;
        while(t--)
        {
            vector<Point> p;
            for(int j=0;j<i;j++) p.pb(randp());
            p=graham(p);
            ans+=sz(p);
        }
        ans/=20000000;
        printf("%.6f,",ans);
    }
    puts("");
}
int main()
{
//    gao();
    double ans[]={0,0,0,3,3.666724,4.166653,4.566743,4.900092,5.185803,5.435999,5.658361};
    int n,i;
    Point p;
    for(i=0;i<3;i++) p.input();
    scanf("%d",&n);
    printf("%.4f\n",ans[n]);
    return 0;
}

code E:



#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define mem(a,b) memset((a),(b),sizeof(a))
#define MP make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)x.size()
#define all(x) x.begin(),x.end()
using namespace __gnu_cxx;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef vector<int> VI;
typedef vector<ll> VL;
const int INF=0x3f3f3f3f;
const ll LLINF=0x3f3f3f3f3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-6;
const int MAX=2e6+10;
const ll mod=1e9+7;
/********************************* head *********************************/
struct hash_table
{
    ull seed;
    ull Hash[MAX],tmp[MAX];
    void set(ull _seed)
    {
        seed=_seed;
    }
    void work(char *s,int n)
    {
        ll i,j;
        tmp[0]=1;
        Hash[0]=0;
        for(i=1; i<=n; i++) tmp[i]=tmp[i-1]*seed;
        for(i=1; i<=n; i++) Hash[i]=(Hash[i-1]*seed+(s[i]-'a'));
    }
    ull get(int l,int r)
    {
        return (Hash[r]-Hash[l-1]*tmp[r-l+1]);
    }
}h;
char s[MAX];
VI res[MAX];
int  main()
{
    while(~scanf("%s",s+1))
    {
        int len = strlen(s+1);
        for(int i=len+1;i<=len*2;i++)
        {
            s[i] = s[i-len];
        }
        //s[2*len+1]= 0;
        h.set(19873);
        h.work(s,len*2);
        unordered_map<ull,int>mp;
        int tot = 0;
        for(int i=1;i<=len;i++)
        {
            ull tmp = h.get(i,i+len-1);
            if(!mp.count(tmp))mp[tmp]=++tot;
            res[mp[tmp]].pb(i-1);
        }
        printf("%d\n",tot);
        for(int i=1;i<=tot;i++)
        {
            printf("%d",sz(res[i]));
            for(auto it:res[i])
            {
                printf(" %d",it);
            }
            puts("");
        }
    }
}

code J:

#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-7;
const double INF = 1e20;
const double pi = acos(-1.0);
int dcmp(double x)
{
    if (fabs(x) < eps) return 0;
    return (x < 0 ? -1 : 1);
}

inline double sqr(double x)
{
    return x * x;
}

struct Point
{
    double x, y;

    Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}

    void input()
    {
        scanf("%lf%lf", &x, &y);
    }

    void output()
    {
        printf("%.2f %.2f\n", x, y);
    }

    bool operator==(const Point &b) const
    {
        return (dcmp(x - b.x) == 0 && dcmp(y - b.y) == 0);
    }

    bool operator<(const Point &b) const
    {
        return (dcmp(x - b.x) == 0 ? dcmp(y - b.y) < 0 : x < b.x);
    }

    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);
    }

    Point operator*(double a)
    {
        return Point(x * a, y * a);
    }

    Point operator/(double a)
    {
        return Point(x / a, y / a);
    }

    double len2() //返回长度的平方
    {
        return sqr(x) + sqr(y);
    }

    double len() //返回长度
    {
        return sqrt(len2());
    }

    Point change_len(double r) //转化为长度为r的向量
    {
        double l = len();
        if (dcmp(l) == 0) return *this;//零向量返回自身
        r /= l;
        return Point(x * r, y * r);
    }



};

double cross(Point a, Point b) //叉积
{

    return a.x * b.y - a.y * b.x;
}

double dot(Point a, Point b) //点积
{

    return a.x * b.x + a.y * b.y;
}

double dis(Point a, Point b) //两个点的距离
{

    Point p = b - a;
    return p.len();
}

double rad(Point a, Point b) //两个向量的夹角
{

    return fabs(atan2(fabs(cross(a, b)), dot(a, b)));
}


//************直线 线段
struct Line
{
    Point s, e;//直线的两个点
    Line() {}
    Line(Point _s, Point _e) : s(_s), e(_e) {}
    double length() //求线段长度
    {
        return dis(s, e);
    }

};

double point_to_line(Point p, Line a) //点到直线的距离
{
    return fabs(cross(p - a.s, a.e - a.s) / a.length());
}

Point projection(Point p, Line a) //点在直线上的投影
{
    return a.s + (((a.e - a.s) * dot(a.e - a.s, p - a.s)) / (a.e - a.s).len2());
}

//***************圆
struct Circle
{
//圆心 半径
    Point p;
    double r;

    Circle() {}

    Circle(Point _p, double _r) : p(_p), r(_r) {}

    Circle(double a, double b, double _r)
    {
        p = Point(a, b);
        r = _r;
    }

    void input()
    {
        p.input();
        scanf("%lf", &r);
    }

    void output()
    {
        p.output();
        printf(" %.2f\n", r);
    }

    bool operator==(const Circle &a) const
    {
        return p == a.p && (dcmp(r - a.r) == 0);
    }

    double area() //面积
    {
        return pi * r * r;
    }

    double circumference() //周长
    {
        return 2 * pi * r;
    }

    bool operator<(const Circle &a) const
    {
        return p < a.p || (p == a.p && r < a.r);
    }
};

int relation(Point p, Circle a) //点和圆的关系
{
//0:圆外 1:圆上 2:圆内
    double d = dis(p, a.p);
    if (dcmp(d - a.r) == 0) return 1;
    return (dcmp(d - a.r) < 0 ? 2 : 0);
}

int relation(Line a, Circle b) //直线和圆的关系
{
//0:相离 1:相切 2:相交
    double p = point_to_line(b.p, a);
    if (dcmp(p - b.r) == 0) return 1;
    return (dcmp(p - b.r) < 0 ? 2 : 0);
}


int line_cirlce_intersection(Line v, Circle u, Point &p1, Point &p2) //直线和圆的交点
{
//返回交点个数 交点保存在引用中
    if (!relation(v, u)) return 0;
    Point a = projection(u.p, v);
    double d = point_to_line(u.p, v);
    d = sqrt(u.r * u.r - d * d);
    if (dcmp(d) == 0)
    {
        p1 = a, p2 = a;
        return 1;
    }
    p1 = a + (v.e - v.s).change_len(d);
    p2 = a - (v.e - v.s).change_len(d);
    return 2;
}

double circle_traingle_area(Point a, Point b, Circle c) //圆心三角形的面积
{
//a.output (), b.output (), c.output ();
    Point p = c.p;
    double r = c.r; //cout << cross (p-a, p-b) << endl;
    if (dcmp(cross(p - a, p - b)) == 0) return 0;
    Point q[5];
    int len = 0;
    q[len++] = a;
    Line l(a, b);
    Point p1, p2;
    if (line_cirlce_intersection(l, c, q[1], q[2]) == 2)
    {
        if (dcmp(dot(a - q[1], b - q[1])) < 0) q[len++] = q[1];
        if (dcmp(dot(a - q[2], b - q[2])) < 0) q[len++] = q[2];
    }
    q[len++] = b;
    if (len == 4 && dcmp(dot(q[0] - q[1], q[2] - q[1])) > 0)
        swap(q[1], q[2]);
    double res = 0;
    for (int i = 0; i < len - 1; i++)
    {
        if (relation(q[i], c) == 0 || relation(q[i + 1], c) == 0)
        {
            double arg = rad(q[i] - p, q[i + 1] - p);
            res += r * r * arg / 2.0;
        }
        else
        {
            res += fabs(cross(q[i] - p, q[i + 1] - p)) / 2;
        }
    }
    return res;
}

double ComputeSignedArea(const vector<Point> &p) //多边形面积 如果小于零,reverse(P.begin(), P.end());再调用一次
{
    double area = 0;
    for (unsigned i = 0; i < p.size(); i++)
    {
        unsigned j = (i + 1) % p.size();
        area += p[i].x * p[j].y - p[j].x * p[i].y;
    }
    return area / 2.0;
}

double area_polygon_circle(Circle c, const vector<Point>& p) //多边形与圆面积
{
    double ans = 0;
    for (int i = 0; i < (int) p.size(); i++)
    {
        int j = (i + 1) % int(p.size());
        if (dcmp(cross(p[j] - c.p, p[i] - c.p)) >= 0)
            ans += circle_traingle_area(p[i], p[j], c);
        else
            ans -= circle_traingle_area(p[i], p[j], c);
    }
    return fabs(ans);
}


//上面是板子

vector<Point>polygon; //存多边形的点
int main()
{
    int n,x,y;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        scanf("%d%d",&x,&y);
        polygon.push_back(Point(x,y));
    }
    double area = ComputeSignedArea(polygon) ;
    if(area<0)
    {
        reverse(polygon.begin(),polygon.end());
        area  = ComputeSignedArea(polygon);
    }
    int q;
    cin>>q;
    while(q--)
    {
        int x,y,p,q;
        cin>>x>>y>>p>>q;
        p = q-p;
        Point o = Point(x,y);
        double l = 0.0,r = 5e6;
        while(r-l>eps)
        {
            double mid = (l+r)*0.5;
            Circle yuan = Circle(o,mid);
            if(q*area_polygon_circle(yuan,polygon)>p*area)
            {
                r = mid;
            }
            else l = mid;

        }
        printf("%.12f\n",l);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值