什么!!!你没有板子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;
}