zoukankan      html  css  js  c++  java
  • 校内集训(20170906)

    emmmm又是200.。

    我大概是永远不会AK?T3我都想到算法了。。(掀桌~)

    切入正题吧。

    ——————————————————我是分割线——————————————————

    T1:切糕(cut)

    【问题描述】

    R意外获得了一块切糕,他准备把切糕分给n个小伙伴。切糕的形状是一个底边长为a,高为b的等腰三角形。小R打算横着或竖着切n-1刀把切糕切成面积相等的n块分给小伙伴,请你告诉他要在哪些地方切。

    【输入格式】

    输入文件cut.in

    输入包含四个整数n,a,b,c,表示要切成n块,切糕的三个顶点分别位于(0,0),(a,0),(a/2,b),若c=0,表示要横着切;若c=1,表示要竖着切。

    【输出格式】

    输出文件cut.out

    输出共n-1行,每行一个实数,从小到大输出各切割处的位置,若c=0,每输出一个整数a,表示在直线y=a处切一刀;若c=1,每输出一个整数a,表示在直线x=a处切一刀。当你的输出与标准输出的绝对误差不超过时,判为正确。

    样例输入1】

    3 5 2 0 

    【样例输出1

    0.3670068381

    0.8452994616

    样例输入2】

    2 5 3 1

    【样例输出2

    2.5

    【数据范围】

    对于全部数据,2<=n<=10001<=a,b<=10^5

    对于50%的数据,c=0

    对于另外50%的数据,c=1

    ——————————————————我是分割线——————————————————

    这题就是暴力模拟切在哪。当然,像学长一样写一个O(1)放扫描线的数论方法当然也是可以的啦;。

    我是二分+暴力emmmm

    下面贴代码

    #include<cstdio>
    using namespace std;
    double a,h;
    int n,c;
    int main(){
        freopen("cut.in","r",stdin);
        freopen("cut.out","w",stdout);
        scanf("%d%lf%lf%d",&n,&a,&h,&c);
        if(c==0){
            double last=0,now=(a*h)/(double)(2*n),tot=(a*h)/2.0;
            double xie=a/h;
            for(int i=1;i<n;i++){
                double l=last,r=h;
                for(int j=1;j<=100;j++){
                    double mid=(l+r)/2.0;
                    if(tot-(h-mid)*xie*(h-mid)/2.0<now)l=mid;
                    else r=mid;
                }
                tot=(h-l)*xie*(h-l)/2.0;
                printf("%.14lf
    ",l);
            }
        }else {
            double qaq[1005];
            int ss=0;
            double last=0,now=(a*h)/(double)(2*n),tot=0;
            double xie=2.0*h/a;
            for(int i=1;i<=(n-1)/2;i++){
                double l=last,r=a/2.0;
                for(int j=1;j<=100;j++){
                    double mid=(l+r)/2.0;
                    if(mid*mid*xie/2.0-tot<now)l=mid;
                    else r=mid;
                }
                tot=l*l*xie/2.0;last=l;
                printf("%.14lf
    ",l);qaq[++ss]=l;
            }
            if((n-1)%2==1)printf("%.14lf
    ",a/2.0);
            tot=a*h/4.0;
            for(int i=ss;i>=1;i--)printf("%.14lf
    ",a-qaq[i]);
        }
        fclose(stdin);
        fclose(stdout);
    }

    ——————————————————我是分割线——————————————————

    T2:采购(buy)

    【问题描述】

    R有一个爱好,他经常去杂货市场上采购一些奇奇怪怪的物品。今天小R来到市场,发现有n个摊位,每个摊位出售不同的货物,第i个摊位出售的货物价格为ai。这些摊位的老板很奇怪,他们不喜欢你购买其他摊位的物品,如果你购买了k件其他摊位的物品,你在购买第i个摊位出售的物品时需要额外支付k*bi的钱,为了防止你买完一个摊位的物品后再去买另一家的物品,他们商量好要求你同时结账,现在小Rm元钱,他想知道自己最多能买多少种不同的物品。

    【输入格式】

    输入文件buy.in

    第一行两个正整数nm,表示摊位数和小R的钱数。

    接下来n行,每行两个非负整数ai,bi,意义同问题描述。 

    【输出格式】

    输出文件buy.out

    输出一个非负整数,表示答案。

    【样例输入】

    3 7

    1 3

    2 1

    3 0

    【样例输出】

    2

    【数据范围】

    对于20%的数据,n<=20

    对于40%的数据,n<=1000

    对于另外10%的数据,bi=0

    对于另外20%的数据,所有bi均相等;

    对于100%的数据,n,ai,bi<=100,000m<=10^9

    ——————————————————我是分割线——————————————————

    这题、。。。。不就是二分枚举取几个,然后暴力给一个新的数组sort嘛。。都不想说啥。

    下面贴代码

    #include<cstdio>
    #include<algorithm>
    #define MN 100005
    using namespace std;
    long long n,m;
    int ans;
    long long b[MN],sum[MN],a[MN];
    int main(){
        freopen("buy.in","r",stdin);
        freopen("buy.out","w",stdout);
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]),sum[i]=a[i];
        int l=0,r=n;
        while(l<=r){
            int mid=(l+r>>1);
            for(int i=1;i<=n;i++)sum[i]=a[i]+(mid-1)*b[i];
            sort(sum+1,sum+n+1);
            long long tot=0;
            for(int i=1;i<=mid;i++)tot+=sum[i];
            if(tot>m)r=mid-1;
            else l=mid+1,ans=mid;
        }
        printf("%d
    ",ans);
        fclose(stdin);
        fclose(stdout);
    }

    注意long long就好啦

    ——————————————————我是分割线——————————————————

    T3:能量(power)

    【问题描述】

    R在某次杂货采购中买到了nXOR能量石,每个能量石有一个能量系数ai和共鸣系数bi,其中能量系数决定了能量石的好坏。小R想知道这些能量石的品质,但能量系数无法简单观测得到,只有通过能量共鸣仪促使能量石之间发生共鸣,才有办法获知能量系数。能量共鸣仪每次可以使一个区间内的所有能量石发生共鸣,并且获知这些能量石能量系数的异或和,但需要消耗等同于区间内所有能量石共鸣系数异或和的能量。小R已经测量出了各个能量石的共鸣系数,现在他想知道至少需要多少能量才能确定所有能量石的能量系数。

    【输入格式】

    输入文件power.in

    第一行一个正整数n,表示能量石的个数。

    第二行n个整数bi,表示各个能量石的共鸣系数。

    【输出格式】

    输出文件power.out

    输出一个整数,表示最小的能量花费。

    【样例输入】

    2

    1 3

    【样例输出】

    3

    【数据范围】

    对于20%的数据,n<=10

    对于50%的数据,n<=100

    对于70%的数据,n<=1,000

    对于100%的数据,n<=10,0000<=bi<2^31

    ——————————————————我是分割线——————————————————

    最气的就是这题啦。我都想到了用mst(最小生成树来做了,没想到可以用prim暴力过啊,而且局部最优性也没有想到,就是为如何单独查找一个点而烦恼了一下,其实直接prim硬上就好了,kruskal反而不好写。。。我是假人,没有认真考虑问题)

    我们想到对于一个区间查询比如[l,r]那么其实我们就是从l到r连了一条权值为a[l]^a[l+1]^...^a[r]的边,然后我们可以前缀和处理连边。。然后就没了。、

    我都做过啊!!都想到了原题还不会做。。。我就是个大**(心累)

    #include<cstdio>
    #define min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    int num[10005],f[10005],n,qaq;
    long long ans;
    bool v[10005];
    int main(){
        freopen("power.in","r",stdin);
        freopen("power.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&qaq),f[i]=num[i]=num[i-1]^qaq;
        for(int i=1;i<=n;i++){
            int best=0;
            for(int j=1;j<=n;j++)if(!v[j]&&(!best||f[j]<f[best]))best=j;
            v[best]=1;ans+=(long long)f[best];
            for(int j=1;j<=n;j++)if(!v[j])f[j]=min(f[j],num[j]^num[best]);
        }
        printf("%lld
    ",ans);
        fclose(stdin);
        fclose(stdout);
    }

    200还是太弱啊,都被falldream学长D的飞起啦!cf最近一天才2题,感觉脸都丢尽了(大概是我菜吧)

    唉,接着努力吧,游戏先扔掉好了(虽然最近没打,不过被老师和同学各种D,还是声明一下好了QAQ)

  • 相关阅读:
    MySQL RR隔离 读一致性
    C++奥赛一本通刷题记录(高精度)
    CodeVs天梯之Diamond
    CodeVs天梯之Gold
    CodeVs天梯之Silver
    CodeVs天梯之Bronze
    【2018.1.14】本蒟蒻又回来了
    test
    UVa12545
    UVa1149
  • 原文地址:https://www.cnblogs.com/ghostfly233/p/7486207.html
Copyright © 2011-2022 走看看