hdu多校第五场题解(>=100人)

版权声明:转载之前请说你是博主的粉丝哦。 https://blog.csdn.net/qq_34921856/article/details/82154263

E - Everything Has Changed
利用余角定理算出弧度,然后乘以半径就行了。acos真牛逼!本来我以为相交还得分两种情况来计算,但实际上列了一个通式之后算出来的结果用acos转换成弧度之后它会自己变成正确的,因为acos的值域为[0,pi]

#include<bits/stdc++.h>
using namespace std;
const double PI=acos(-1.0);
const double eps=1e-9;
inline int sgn(double x)
{
    if(fabs(x)<eps)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<bits/stdc++.h>
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;i<len;i++)
        res=res*10+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;i<len;i++)
    {
        if(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;i<len;i++)
    {
        char it=s[i];
        int idx=-1;
        for(int j=i+1;j<len;j++)
        {
            if(s[j]<it)
            {
                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<<s<<' '<<b<<endl;
            continue;
        }
        dfs(0,0);
        cout<<minans<<' '<<maxans<<endl;
    }
    return 0;
}

G - Glad You Came
晕,一开始就想到了用线段树,然后用最小值最大值来进行剪枝,然而怎么写怎么T,原因是最后统计答案的时候还可以剪枝。。晕。。

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cstring>
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<<l<<' '<<r<<' '<<v<<' '<<query(1,1,n,1)<<' '<<query(2,1,n,1)<<endl;
        }
        long long ans=0;
        query(1,n,1);
        for(int i=1;i<=n;i++)
        {
            ans=ans^(1LL*i*a[i]);
        }
        printf("%lld\n",ans);
    }
    return 0;



}

猜你喜欢

转载自blog.csdn.net/qq_34921856/article/details/82154263