Self-Assembly

拆点连边,用拓扑排序判定有没有环

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}


#define MAXN (40000+10)
struct Topsort{
int n,indegree[MAXN];
vi e[MAXN];
int q[MAXN*4];
void init(int _n) {
n=_n;
Rep(i,n) e[i].clear();
MEM(indegree)
}
void addedge(int u,int v) {
e[u].pb(v); indegree[v]++;
}
int topsort()
{
MEM(q)
int head_=1,tail=0;
Rep(i,n)
if (indegree[i]==0)
{
q[++tail]=i;
}

while (head_<=tail)
{
int now=q[head_];
Rep(i,SI(e[now]))
{
int v=e[now][i];
indegree[v]--;
if (indegree[v]==0)
{
q[++tail]=v;
}
}
head_++;
}
return tail==n;
}
}S1;

int n;
int id(char *s) {
if (s[1]=='+') return (s[0]-'A');
if (s[1]=='-') return (26+s[0]-'A');
return 52;
}
int h(int i,int j) {
return 53*i+j;
}
int l(int i) {
return i/53;
}
int r(int i) {
return i%53;
}

int a[MAXN][4];
bool b[MAXN];
bool con(int i,int j) {
int u=r(i),v=l(j);
if (u<26&&v==u+26) return 1;
if (v<26&&u==v+26) return 1;


return 0;
}

int main()
{
// freopen("A.in","r",stdin);
// freopen(".out","w",stdout);
while(cin>>n) {
MEM(b)
Rep(i,n) {
char s[10];
scanf("%s",s);
Rep(j,4) a[i][j]=id(s+j*2);
Rep(j,4) {
int k=(j+1)%4;
int l=(k+1)%4;
b[h(a[i][j],a[i][k])]=1;
b[h(a[i][k],a[i][j])]=1;
b[h(a[i][j],a[i][l])]=1;
}
}
S1.init(53*53);
Rep(i,53*53) if (b[i]) Rep(j,53*53) if (b[j]&&con(i,j)) {
// cout<<i<<' '<<j<<endl;
S1.addedge(i,j);
}

bool flag=S1.topsort();
puts(flag?"bounded":"unbounded");
}


return 0;
}

Low Power

二分+贪心

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (200000+10)
int a[MAXN];
int n,K,m;
bool check(int d) {
int p=0;
For(i,m-1) {
if (p>=n) break;

if (a[i+1]-a[i]<=d) p++,i++;
else {
if(i<=2*p*K) continue;
break;
}
}
return p>=n;
}
int main()
{
// freopen("f.in","r",stdin);
// freopen(".out","w",stdout);
while(cin>>n>>K) {
For(i,2*n*K) scanf("%d",&a[i]);
m=2*n*K;

sort(a+1,a+1+m);
int ans=0;
check(0);
int l=0,r=1e9;
while(l<=r) {
int m=(r+l)/2;
if (check(m)) ans=m,r=m-1;else l=m+1;
}
cout<<ans<<endl;
}


return 0;
}

Pollution Solution

多边形与圆的面积并
三角剖分,然后套三角形与圆的面积并的板子

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %I64d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
ll sqr(ll a){return a*a;}
ld sqr(ld a){return a*a;}
double sqr(double a){return a*a;}

ld PI = 3.141592653589793238462643383;
class P{
public:
ld x,y;
P(long double x=0,long double y=0):x(x),y(y){}
friend long double dis2(P A,P B){return sqr(A.x-B.x)+sqr(A.y-B.y); }
friend long double Dot(P A,P B) {return A.x*B.x+A.y*B.y; }
friend long double Length(P A) {return sqrt(Dot(A,A)); }
friend long double Angle(P A,P B) {return acos(Dot(A,B) / Length(A) / Length(B) ); }

friend P operator- (P A,P B) { return P(A.x-B.x,A.y-B.y); }
friend P operator+ (P A,P B) { return P(A.x+B.x,A.y+B.y); }
friend P operator* (P A,double p) { return P(A.x*p,A.y*p); }
friend P operator/ (P A,double p) { return P(A.x/p,A.y/p); }
friend bool operator< (const P& a,const P& b) {return a.x<b.x||(a.x==b.x&& a.y<b.y);}

};
const ld eps=1e-14;
int dcmp(ld x) {
if (fabs(x)<eps) return 0; else return x<0 ? -1 : 1;
}
bool operator==(const P& a,const P& b) {
return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y) == 0;
}
typedef P V;

double Cross(V A,V B) {return A.x*B.y - A.y*B.x;}
double Area2(P A,P B,P C) {return Cross(B-A,C-A);}
V Rotate(V A,double rad) {
return V(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
// A 不是 0向量
V Normal(V A) {
double L = Length(A);
return V(-A.y/L , A.x/L);
}

//Cross(v,w)==0(平行)时,不能调这个函数
P GetLineIntersection(P p,V v,P Q,V w){
V u = p-Q;
double t = Cross(w,u)/Cross(v,w);
return p+v*t;
}
double DistanceToLine(P p,P A,P B) {
V v1 = B-A, v2 = p-A;
return fabs(Cross(v1,v2))/Length(v1);
}
double DistanceToSegment(P p,P A,P B) {
if (A==B) return Length(p-A);
V v1 = B-A, v2 = p-A, v3 = p - B;
if (dcmp(Dot(v1,v2))<0) return Length(v2);
else if (dcmp(Dot(v1,v3))>0 ) return Length(v3);
else return fabs(Cross(v1,v2) ) / Length(v1);
}
P GetLineProjection(P p,P A,P B) {
V v=B-A;
return A+v*(Dot(v,p-A)/Dot(v,v));
}
//规范相交-线段相交且交点不在端点
bool SegmentProperIntersection(P a1,P a2,P b1,P b2) {
double c1 = Cross(a2-a1,b1-a1) , c2 = Cross(a2-a1,b2-a1),
c3 = Cross(b2-b1,a1-b1) , c4 = Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
//点在线段上(不包含端点)
bool OnSegment(P p,P a1,P a2) {
return dcmp(Cross(a1-p,a2-p)) == 0 && dcmp(Dot(a1-p,a2-p))<0;
}
double ConvexPolygonArea(P *p,int n) {
double area=0;
For(i,n-2) area+=Cross(p[i]-p[0],p[i+1]-p[0]);
return area/2;
}
/*欧拉公式: V+F-E=2
V-点数 F面数 E边数 */
P read_point() {
P a;
scanf("%lf%lf",&a.x,&a.y);
return a;
}
struct C{
P c;
double r,x,y;
C(){}
C(P c,double r):c(c),r(r),x(c.x),y(c.y){}
P point(double a) {
return P(c.x+cos(a)*r,c.y+sin(a)*r);
}
};

struct Line{
P p;
V v;
double ang;
Line(){}
Line(P p,V v):p(p),v(v) {ang=atan2(v.y,v.x); }
bool operator<(const Line & L) const {
return ang<L.ang;
}
P point(double a) {
return p+v*a;
}
};
int getSegCircleIntersection(Line L,C cir,vector<P> & sol) {
if (dcmp(DistanceToLine(cir.c,L.p,L.p+L.v)-cir.r)==0) {
P A= GetLineProjection(cir.c,L.p,L.p+L.v);
if (OnSegment(A,L.p,L.p+L.v) || L.p==A || L.p+L.v==A )
sol.pb(A);
return sol.size();
}
double t1,t2;
double a = L.v.x, b = L.p.x - cir.c.x, c = L.v.y, d= L.p.y - cir.c.y;
double e = a*a+c*c, f = 2*(a*b + c*d), g = b*b+d*d-cir.r*cir.r;
double delta = f*f - 4*e*g;
if (dcmp(delta)<0) return 0;
else if (dcmp(delta)==0) {
t1 = -f / (2*e);
if (0<=t1&&t1<=1) {
sol.pb(L.point(t1));
}
return sol.size();
}
t1 = (-f - sqrt(delta)) / (2*e); if (0<=t1&&t1<=1) sol.pb(L.point(t1));
t2 = (-f + sqrt(delta)) / (2*e); if (0<=t2&&t2<=1) sol.pb(L.point(t2));
if (0<=t2&&t2<t1&&t1<=1) swap(sol[0],sol[1]);
return sol.size();
}
double angle(V v) {return atan2(v.y,v.x);}

int isPointInOrOnCircle(P p,C c) {
return dcmp(Length(p-c.c)-c.r)<=0;
}

int n;
P p[200],O(0,0);
int main()
{
// freopen("J.in","r",stdin);
// freopen(".out","w",stdout);
while(cin>>n&&n) {
double R; cin>>R;
Rep(i,n) {
cin>>p[i].x>>p[i].y;
}
{
double m=R,ans=0;
C c=C(P(),m);
Rep(i,n) {
int j=(i+1)%n;
bool b = isPointInOrOnCircle(p[i],c);
bool b2 = isPointInOrOnCircle(p[j],c);
double opr;
if (Area2(O,p[i],p[j])>=0) opr=1; else opr=-1;
// cout<<opr<<endl;

if (b&&b2) {
ans+=opr*fabs(Area2(p[i],p[j],O))/2;
} else if (!b&&!b2){
Line l=Line(p[i],p[j]-p[i]);
vector<P> sol;
getSegCircleIntersection(l,c,sol);
if (SI(sol)==2) {
ans+=opr*fabs(Area2(sol[0],sol[1],O))/2;
ans+=opr*m*m/2*(Angle(p[i],sol[0])+Angle(sol[1],p[j]));
} else {
ans+=opr*m*m/2*(Angle(p[i],p[j]));
}
} else {
Line l=Line(p[i],p[j]-p[i]);
vector<P> sol;
getSegCircleIntersection(l,c,sol);
if(b) {
ans+=opr*fabs(Area2(sol[0],p[i],O))/2;
ans+=opr*m*m/2*(Angle(sol[0],p[j]));
} else {
ans+=opr*fabs(Area2(sol[0],p[j],O))/2;
ans+=opr*m*m/2*(Angle(sol[0],p[i]));
}
}
}
ans=max(ans,-ans);
printf("%.9lf\n",ans);
}


}

return 0;
}