E - Everything Has Changed
利用余角定理算出弧度,然后乘以半径就行了。acos真牛逼!本来我以为相交还得分两种情况来计算,但实际上列了一个通式之后算出来的结果用acos转换成弧度之后它会自己变成正确的,因为acos的值域为[0,pi]
#include
using namespace std;
const double PI=acos(-1.0);
const double eps=1e-9;
inline int sgn(double x)
{
if(fabs(x)return 0;
if(x>0)return 1;
return -1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int m;
double R;
scanf("%d %lf",&m,&R);
double ans=2*PI*R;
while(m--)
{
double x,y,r;
scanf("%lf %lf %lf",&x,&y,&r);
double d=sqrt(x*x+y*y);
if(sgn(d-r-R)>=0||sgn(d-(R-r))<0)continue;
if(sgn(d-(R-r))==0)
ans+=2*PI*r;
else
{
double yy=(d*d-R*R+r*r)/(2*d*r);
double xx=(R*R+d*d-r*r)/(2*d*R);
double delta1=acos(yy)*2;
double delta2=acos(xx)*2;
ans+=delta1*r;
ans-=delta2*R;
}
}
printf("%.7f\n",ans);
}
return 0;
}
B - Beautiful Now
一开始写了一个假算法,感觉很正确,写博客的时候突然造了一个样例hack了。
void getmax(char *s)
{
int len=strlen(s+1);
int kk=k;
for(int i=1; i<=len&&kk; i++)
{
char it=s[i];
int idx=-1;
for(int j=len; j>i; j--)
{
if(s[j]>it)
{
it=s[j];
idx=j;
}
}
if(idx!=-1)
{
swap(s[i],s[idx]);
kk--;
}
}
}
这是那个假算法,虽然能得到最大的,但不一定是次数最小的,比如7699,按照这个就要花3次,实际上2次就行了。。唉。
正确答案也很简单,直接暴力就完事了。毕竟也就10!种状态
#include
using namespace std;
string s;
bool cmp(char a,char b)
{
return a>b;
}
int minans,maxans;
int k,len;
int getnum()
{
int res=0;
for(int i=0;i10+s[i]-'0';
return res;
}
void dfs(int d,int c)
{
int num=getnum();
if(d==len-1||c==k)
{
minans=min(minans,num);
maxans=max(maxans,num);
return;
}
minans=min(minans,num);
maxans=max(maxans,num);
for(int i=d+1;iif(d==0&&s[i]=='0')continue;
swap(s[i],s[d]);
dfs(d+1,c+1);
swap(s[i],s[d]);
}
dfs(d+1,c);
}
void solve()
{
for(int i=0;ichar it=s[i];
int idx=-1;
for(int j=i+1;jif(s[j]if(i==0&&s[j]!='0'||i!=0)
{
it=s[j];
idx=j;
}
}
}
if(idx!=-1)swap(s[i],s[idx]);
}
}
int main()
{
int T;
std::ios::sync_with_stdio(false);
cin>>T;
while(T--)
{
minans=1e9+10;
maxans=0;
cin>>s;
cin>>k;
len=s.size();
if(k>=len)
{
string b=s;
sort(b.begin(),b.end(),cmp);
solve();
cout<' '<continue;
}
dfs(0,0);
cout<' '<return 0;
}
G - Glad You Came
晕,一开始就想到了用线段树,然后用最小值最大值来进行剪枝,然而怎么写怎么T,原因是最后统计答案的时候还可以剪枝。。晕。。
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+5;
unsigned X,Y,Z;
unsigned RNG61()
{
X=X^(X<<11);
X=X^(X>>4);
X=X^(X<<5);
X=X^(X>>14);
unsigned W=X^(Y^Z);
X=Y;
Y=Z;
Z=W;
return Z;
}
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
struct node
{
int ma;
int mi;
int lazy;
}nodes[maxn<<2];
void build(int l,int r,int rt)
{
if(l==r)
{
nodes[rt].ma=0;
nodes[rt].mi=0;
nodes[rt].lazy=0;
return;
}
int m=l+r>>1;
build(ls);
build(rs);
nodes[rt].lazy=0;
nodes[rt].ma=0;
nodes[rt].mi=0;
}
void pushdown(int rt)
{
if(nodes[rt].lazy)
{
nodes[rt<<1].ma=nodes[rt].lazy;
nodes[rt<<1].lazy=nodes[rt].lazy;
nodes[rt<<1|1].ma=nodes[rt].lazy;
nodes[rt<<1|1].lazy=nodes[rt].lazy;
nodes[rt<<1].mi=nodes[rt].lazy;
nodes[rt<<1|1].ma=nodes[rt].lazy;
nodes[rt].lazy=0;
}
}
void pushup(int rt)
{
nodes[rt].ma=max(nodes[rt<<1].ma,nodes[rt<<1|1].ma);
nodes[rt].mi=min(nodes[rt<<1].mi,nodes[rt<<1|1].mi);
}
void update(int L,int R,int C,int l,int r,int rt)
{
if(nodes[rt].mi>=C)return;
if(L<=l&&r<=R)
{
if(l==r)
{
nodes[rt].ma=max(nodes[rt].ma,C);
nodes[rt].mi=nodes[rt].ma;
return;
}
if(nodes[rt].ma<=C)
{
nodes[rt].ma=C;
nodes[rt].mi=C;
nodes[rt].lazy=C;
return;
}
}
pushdown(rt);
int m=l+r>>1;
if(L<=m)update(L,R,C,ls);
if(R>m)update(L,R,C,rs);
pushup(rt);
}
int a[maxn];
void query(int l,int r,int rt)
{
if(nodes[rt].ma==nodes[rt].mi||l==r)
{
for(int i=l;i<=r;i++)
a[i]=nodes[rt].ma;
return;
}
int m=l+r>>1;
pushdown(rt);
query(ls);
query(rs);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d %d %u %u %u",&n,&m,&X,&Y,&Z);
build(1,n,1);
for(int i=1;i<=m;i++)
{
int tmp1=RNG61()%n+1;
int tmp2=RNG61()%n+1;
int v=RNG61()%(1<<30);
int l=min(tmp1,tmp2),r=max(tmp1,tmp2);
update(l,r,v,1,n,1);
//cout<' '<' '<' '<1,1,n,1)<<' '<2,1,n,1)<0;
query(1,n,1);
for(int i=1;i<=n;i++)
{
ans=ans^(1LL*i*a[i]);
}
printf("%lld\n",ans);
}
return 0;
}