2018 Multi-University Training Contest 5

 

 

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值