hdu 6354 Everything Has Changed
http://acm.hdu.edu.cn/showproblem.php?pid=6354
计算1个大圆被若干个小圆切割后剩下部分的周长。
且内涵小圆 外切小圆 外离小圆 都不算。 且这些小圆不会包含大圆且相互不会有重合部分。
那么对于每一个小圆,如果是内切大圆则直接加上这个小圆的周长。
如果是相交,则判断公共弦的位置,如果在2个圆心的两侧,则答案是加一个长弧减一个短弧或者是加一个短弧减一个长弧
如果该弦在2个圆心中间,则是加上一个短弧减去一个短弧。
#include<bits/stdc++.h>
using namespace std;
struct point{
double x;
double y;
};
double dis(point p1,point p2)
{
double dx=p1.x-p2.x;
double dy=p1.y-p2.y;
return sqrt(dx*dx+dy*dy);
}
point inter(point u1,point u2,point v1,point v2)
{
point ret=u1;
double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ret.x+=(u2.x-u1.x)*t;
ret.y+=(u2.y-u1.y)*t;
return ret;
}
void ilc(point c,double r,point l1,point l2,point& p1,point& p2)
{
point p=c;
double t;
p.x+=l1.y-l2.y;
p.y+=l2.x-l1.x;
p=inter(p,c,l1,l2);
t=sqrt(r*r-dis(p,c)*dis(p,c))/dis(l1,l2);
p1.x=p.x+(l2.x-l1.x)*t;
p1.y=p.y+(l2.y-l1.y)*t;
p2.x=p.x-(l2.x-l1.x)*t;
p2.y=p.y-(l2.y-l1.y)*t;
}
void icc(point c1,double r1,point c2,double r2,point& p1,point& p2)
{
point u,v;
double t;
t=(1.0+(r1*r1-r2*r2)/dis(c1,c2)/dis(c1,c2))/2.0;
u.x=c1.x+(c2.x-c1.x)*t;
u.y=c1.y+(c2.y-c1.y)*t;
v.x=u.x+c1.y-c2.y;
v.y=u.y-c1.x+c2.x;
ilc(c1,r1,u,v,p1,p2);
}
int main(){
int t;
cin>>t;
double pi=acos(-1.0);
while(t--)
{
int n;
double R;
scanf("%d %lf",&n,&R);
double L=R*2*pi;
double x,y,r;
while(n--)
{
scanf("%lf%lf%lf",&x,&y,&r);
if((x*x+y*y)<(r-R)*(r-R))
continue;
if(x*x+y*y>=(r+R)*(R+r))
continue;
if(x*x+y*y==(R-r)*(R-r))
{
L+=r*2.0*pi;
}
else{
point j1,j2;
point xy;
xy.x=x;
xy.y=y;
point dy;
dy.x=0;
dy.y=0;
icc(dy,R,xy,r,j1,j2);
double dd=dis(j1,j2);
double jd=acos((2*r*r-dd*dd)/(2*r*r));
double jd1=acos((2*R*R-dd*dd)/(2*R*R));
double lq=r*jd;
double lq1=R*jd1;
double lb=sin(jd1)*R*R/dd;
double lb1=sin(jd)*r*r/dd;
if(lb1*lb1>=x*x+y*y&&lb1*lb1>=lb*lb)
{
L=L-(2*R*pi-lq1)+lq;
}
else if(lb*lb>=x*x+y*y&&lb*lb>=lb1*lb1)
{
L=L-lq1+2.0*r*pi-lq;
}
else{
L=L-lq1+lq;
}
}
}
printf("%.20lf\n",L);
}
return 0;
}
hdu 6351 Beautiful Now
http://acm.hdu.edu.cn/showproblem.php?pid=6351
暴力dfs即可。。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=998244353;
int n,k;
int a[30];
int minn,maxn;
int m;
void dfs(int now,int num)
{
if(now==1||num==k)
{
int z=0;
for(int i=m;i>=1;i--)
{
z=z*10+a[i];
}
//cout<<z<<endl;
if(a[m]!=0)
{
minn=min(z,minn);
maxn=max(z,maxn);
}
return;
}
dfs(now-1,num);
for(int i=now-1;i>=1;i--)
{
swap(a[now],a[i]);
dfs(now-1,num+1);
swap(a[now],a[i]);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
maxn=0;
minn=1e9+7;
scanf("%d%d",&n,&k);
m=0;
while(n)
{
a[++m]=n%10;
n/=10;
}
dfs(m,0);
printf("%d %d\n",minn,maxn);
}
return 0;
}
hdu 6356 Glad You Came
http://acm.hdu.edu.cn/showproblem.php?pid=6356
线段树处理区间最小值,然后每更新一个数字,则更新该区间的最小值。
据说因为范围是随机的且都是2的n次方,所以应该不会出现极端数据
最后1918ms过的
#include<bits/stdc++.h>
using namespace std;
#define ll long long
//priority_queue<ull,vector<ull>,greater<ull> > que;
const int maxn=1e5+10;
const int inf=0x7fffffff;
unsigned x,y,z;
int n,m;
unsigned tang()
{
unsigned t;
x^=x<<11;
x^=x>>4;
x^=x<<5;
x^=x>>14;
t=x;
x=y;
y=z;
z=t^x^y;
return z;
}
ll minn[maxn<<2];
void update(int l,int r,int L,int R,ll k,int h)
{
if(minn[h]>=k)
{
return;
}
if(l==r)
{
minn[h]=max(minn[h],k);
return;
}
int mid=(l+r)/2;
if(L<=mid)update(l,mid,L,R,k,h*2);
if(R>mid)update(mid+1,r,L,R,k,h*2+1);
minn[h]=min(minn[h*2],minn[h*2+1]);
}
ll ans[111111];
void query(int x,int l,int r)
{
if(l==r)
{
ans[l]=minn[x];
return ;
}
int mid=(l+r)/2;
query(x*2,l,mid);
query(x*2+1,mid+1,r);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>n>>m>>x>>y>>z;
for(int i=1;i<=4*n;i++)
minn[i]=0;
for(int i=1;i<=m;i++)
{
unsigned h=tang(),hh=tang(),hhh=tang();
int l=min((h%n)+1,(hh%n)+1);
int r=max((h%n)+1,(hh%n)+1);
int v=hhh%(1<<30);
update(1,n,l,r,v,1);
}
query(1,1,n);
long long aa=0;
for(long long i=1;i<=n;i++)
{
aa=aa^(i*ans[i]);
}
cout<<aa<<endl;
}
return 0;
}