test20181219(期末考试)

Written with StackEdit.

\(noip\)爆炸后就好久没考试了...结果今天又被抓去,感觉很慌啊...

  • 考完了.过来填坑.

T1

Description

使得\(x^x\)达到或超过\(n\)位数字的最小正整数\(x\)是多少?

Input

输入一个正整数\(n(n<=2*10^9)\)

Output

输出使得\(x^x\)达到\(n\)位数字的最小正整数\(x\)

Sample Input

11

Sample Output

10

Solution

  • \(x^x\geq 10^{n-1}\).对\(10\)去取对数,等价于\(xlog_{10}x\geq n-1.\)
  • 二分\(x\),用\(cmath\)库自带的\(log10\)函数检验即可.
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int out=0,sgn=1;
    char jp=getchar();
    while(jp!='-' && (jp>'9' || jp<'0'))
        jp=getchar();
    if(jp=='-')
        jp=getchar(),sgn=-1;
    while(jp>='0' && jp<='9')
        out=out*10+(jp-'0'),jp=getchar();
    return out*sgn;
}
using namespace std;
long long fpow(int a,int b)
{
    long long s=1;
    while(b)
        {
            if(b&1)
                s*=a;
            a*=a;
            b>>=1;
        }
    return s;
}
double count(long long x)
{
    double y=x*1.0;
    return y*log10(y);
}
int main()
{
    freopen("xx.in","r",stdin);
    freopen("xx.out","w",stdout);
    int n=read();
    double x=(n-1)*1.0;
    long long L=1,R=1000000000000000000;
    long long ans=R+1;
    while(L<=R)
        {
            long long mid=(L+R)>>1;
            if(count(mid)>=x)
                R=mid-1,ans=min(ans,mid);
            else
                L=mid+1;
        }
    cout<<ans<<endl;
    return 0;
}

T2

Description

和所有人一样,奶牛喜欢变化。它们正在设想新造型的牧场。奶牛建筑师\(Hei\)想建造围有漂亮白色栅栏的三角形牧场。她拥有\(N(3≤N≤40)\)块木板,每块的长度\(L_i(1≤L_i≤40\))都是整数,她想用所有的木板围成一个三角形使得牧场面积最大。

请帮助\(Hei\)小姐构造这样的牧场,并计算出这个最大牧场的面积。

Input

\(1\)行:一个整数\(N.\)

\(2..N+1\)行:每行包含一个整数,即是木板长度。

Output

仅一个整数:最大牧场面积乘以\(100\)然后舍尾的结果。如果无法构建,输出\(-1\)

Sample Input

5 1 1 3 3 4

Sample Output

692

HINT

\(692=\)舍尾后的(\(100×\)三角形面积),此三角形为等边三角形,边长为\(4\)

Solution

  • 考场上做不出来...怒水了一发\(dfs\),居然有\(70pts.\)
  • 将所有的木板当作背包,木板的长度作为背包的重量。与普通背包问题不同的是,这里有两个背包。所以,我们要求的不是重量\(w\)是否能得到,而是一个重量二元组\((w0, w1)\)是否能得到。求解的方法与普通背包问题基本相同,只不过状态是二维的。

  • 求得所有可以得到的二元组后,枚举所有的二元组。对于任意的\((w_0, w_1),w_0, w_1,w—w_0—w_1(w\)表示所有背包的总重量)即是对应的三角形三边之长(可能是非法三角形)。这些三角形中面积最大者就是我们所求的答案。

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main()
{

    freopen("pasture.in" , "r", stdin );
    freopen("pasture.out", "w", stdout);
    bool f[841][841]= {0};
    int n,b[40],i,j,s=0,k;
    double m=0,p,t;
    cin>>n;
    for(i=0; i<n; i++)
        {
            cin>>b[i];
            s+=b[i];
        }
    f[0][0]=true;
    for(k=0; k<n; k++)
        for(i=s/2; i>=0; i--)
            for(j=i; j>=0; j--)
                if(f[i][j])
                    {
                        f[i][j+b[k]]=true;
                        f[i+b[k]][j]=true;
                    }
    p=s/2.0;
    for(i=1; i<p; i++)
        for(j=1; j<=i; j++)
            if(f[i][j]==true&&((i+j)>(s-i-j))&&((i-j)<(s-i-j)))
                {
                    t=p*(p-i)*(p-j)*(p-(s-i-j));
                    if(m<t) m=t;
                }
    if(m<=0)cout<<"-1"<<endl;
    else cout<<int(sqrt(m)*100)<<endl;
    return 0;
}

T3

<[endif]-->

【问题描述】

\(N\)最近学习了位运算,她发现\(2\)个数\(xor\)之后数的大小可能变大也可能变小,\(and\)之后都不会变大,\(or\)之后不会变小。于是她想算出以下的期望值:现在有 \(N\)个数排成一排,如果她随意选择一对\(l,r\)并将下标在\(l\)\(r\)中间(包括\(l,r\))的数\((xor,and,or)\)之后,期望得到的值是多少呢?取出每一对\(l,r\) 的概率都是相等的。(\(l>r\)也被视作有意义).

Input

第一行\(1\)个正整数\(N\)

第二行\(N\)个非负整数代表数列.

Output

一行\(3\)个数,分别表示\(xor\)的期望,\(and\)的期望,\(or\)的期望,保留\(3\)位小数。

Sample Input

2

4 5

Sample Output

2.750 4.250 4.750

HINT

\(30\%\)数据中\(1<=N<=1000.\)

对于另外的\(30\%\)数据数列中只包含\(0\)\(1\).

对于\(100\%\)的数据\(1<=N<=100000\),数列中的数 \(\leq 10^9.\)

Solution

  • 可以先求出每个的区间的\((xor,and,or)\)总和,再除以区间总数.
  • 显然,每一位可以分开计算.下面以\(xor\)为例.
  • 考虑对于每一位,有若干个\(0/1\),只用考虑贡献为\(1\)的区间,显然这样的区间内有奇数个\(1\).
  • \(f[i][0/1]\)为区间右端点为\(i\),区间内有偶数/奇数个\(1\)的区间数目.这里只考虑\(l\leq r\),最终答案可以通过简单操作得到.
  • \(and,or\)的计算方法类似,适当修改一下\(0/1\)这一位的定义就可以了.
#include<bits/stdc++.h>
using namespace std;
#define rg register
#define il inline
inline int read()
{
    int out=0,sgn=1;
    char jp=getchar();
    while(jp!='-' && (jp>'9' || jp<'0'))
        jp=getchar();
    if(jp=='-')
        jp=getchar(),sgn=-1;
    while(jp>='0' && jp<='9')
        out=out*10+(jp-'0'),jp=getchar();
    return out*sgn;
}
const int MAXN=1e5+10;
int a[MAXN];
int x[MAXN][40];
long long f[MAXN][2];
int n,lim=0;
long long tot=0;
double xor1=0,and1=0,or1=0;
long long xor2=0,and2=0,or2=0;
il void dp_xor(int j)
{
    f[0][0]=0,f[0][1]=0;
    long long res=0;
    for(rg int i=1;i<=n;++i)
        {
            #define val x[i][j]
            if(val)
                {
                    f[i][0]=f[i-1][1];
                    f[i][1]=f[i-1][0]+1;
                }
            else
                {
                    f[i][0]=f[i-1][0]+1;
                    f[i][1]=f[i-1][1];
                }
            res+=f[i][1];
        }
    xor2+=res<<j;
}
il void dp_and(int j)
{
    f[0][1]=0;
    long long res=0;
    for(rg int i=1;i<=n;++i)
        {
            #define val x[i][j]
            if(val)
                f[i][1]=f[i-1][1]+1;
            else
                f[i][1]=0;
            res+=f[i][1];
        }
    and2+=res<<j;
}
il void dp_or(int j)
{
    f[0][0]=f[0][1]=0;
    long long res=0;
    for(rg int i=1;i<=n;++i)
        {
            #define val x[i][j]
            if(val)
                {
                    f[i][0]=0;
                    f[i][1]=f[i-1][0]+f[i-1][1]+1;
                }
            else
                {
                    f[i][0]=f[i-1][0]+1;
                    f[i][1]=f[i-1][1];
                }
            res+=f[i][1];
        }
    or2+=res<<j;
}
void solve_xor()
{
    for(rg int i=0;i<=lim;++i)
        dp_xor(i);
    xor2<<=1;
    for(rg int i=1;i<=n;++i)
        xor2-=1LL*a[i];
    xor1=1.0*xor2/(1.0*n*n);
}
void solve_and()
{
    for(rg int i=0;i<=lim;++i)
        dp_and(i);
    and2<<=1;
    and2-=tot;
    and1=1.0*and2/(1.0*n*n);
}
void solve_or()
{
    for(rg int i=0;i<=lim;++i)
        dp_or(i);
    or2<<=1;
    or2-=tot;
    or1=1.0*or2/(1.0*n*n);
}
int main()
{
    freopen("nine.in","r",stdin);
    freopen("nine.out","w",stdout);
    n=read();
    for(rg int i=1;i<=n;++i)
        {
            a[i]=read();
            tot+=1LL*a[i];
            int k=a[i];
            int j=-1;
            while(k)
                {
                    ++j;
                    x[i][j]=k&1;
                    k>>=1;  
                }
            lim=max(lim,j);
        }
    if(lim<0)
        {
            puts("0.000 0.000 0.000");
            return 0;
        }
//  cerr<<lim<<endl;
    solve_xor();
    solve_and();
    solve_or();
    printf("%.3lf %.3lf %.3lf\n",xor1,and1,or1);
    //cout<<xor2<<' '<<and2<<' '<<or2<<' '<<endl;
    return 0;
}
//2 4 5

猜你喜欢

转载自www.cnblogs.com/jklover/p/10148704.html