首页 > 其他 > 详细

2019/9/15 校内模拟赛 考试报告

时间:2019-09-15 18:36:55      阅读:101      评论:0      收藏:0      [点我收藏+]

stick

题意

\(k\)根火柴棒,将这\(k\)根火柴棒恰好用完,能拼出的最小和最大的数分别是多少.

思路

最大的数规律很明显.

对于最小的数,爆搜打表找规律,发现大于某个值之后出现类似循环节的结构.

打表代码

#include<bits/stdc++.h>
int F[]={6,2,5,5,4,5,6,3,7,6};
long long Ans;

void DFS(long long now,int R,bool Lead)
{
    if(R==0)
    {
        if(now!=0)
            Ans=std::min(Ans,now);
        return;
    }
    if(now>Ans)return;
    for(int i=0;i<=9;i++)
    {
        if(Lead&&i==0)continue;
        if(R-F[i]>=0)
            DFS(now*10+i,R-F[i],0);     
    }

}

int main()
{
    for(int k=2;k<=100;k++)
    {
        Ans=0x7FFFFFFFFFFFFFFF;
        DFS(0,k,1);
        printf("%d %lld\n",k,Ans);  
    }
    return 0;
}

AC代码

#include<bits/stdc++.h>
int k;
long long F[105]={0,0,1,7,4,2,6,8,10,18,22,20,28,68,88,108,188,200,208,288,688,888,1088,1888,2008,2088,2888,6888,8888};

int main()
{
    freopen("stick.in","r",stdin);
    freopen("stick.out","w",stdout);
    F[29]=10888;
    F[30]=18888;
    F[31]=20088;
    F[32]=20888;
    F[33]=28888;
    F[34]=68888;
    F[35]=88888;
    for(int i=36;i<=100;i++)
        F[i]=F[i-7]*10+8;
    
    std::cin>>k;
    std::cout<<F[k]<<" ";
    if(k%2==1)
    {
        std::cout<<7;
        k-=3;
    }
    while(k)
    {
        std::cout<<1;
        k-=2;
    }
    return 0;
}

board

题目

要将一个长为\(l\)宽为\(w\)的矩形木板(厚度忽略)平铺着拖过一个 L 型过道。

技术分享图片

如图所示,L 型过道的两个走廊的宽度分别是\(a\)\(b\),呈 90°,并且走廊的长度远大于\(l\)

对于给定的\(a,b,l\),最大的\(w\)是多少,如果无论如何木板都不可能通过,则输出"My poor head =(" .

思路

转化为几何模型.

技术分享图片

如图,建立直角坐标系,三分横截距,勾股定理计算纵截距,解出直线的方程,计算点到直线的距离.

注意特判某些特殊情况.

代码

#include<bits/stdc++.h>
#define DB double
#define eps (1e-10)
DB A,B,L,Ans;

DB Dis(DB A,DB B,DB C,DB X,DB Y)//点到直线距离 
{
    DB N=A*X+B*Y+C;
    DB M=sqrt(A*A+B*B);
    return N/M;
}

int main()
{
    std::cin>>A>>B>>L;
    if(A-B>eps)std::swap(A,B);
    if(B+eps>L)Ans=A;//特判 
    else
    {
        DB s=0,e=L;
        while(e-s>eps)//三分横截距 
        {
            DB X1=s+(e-s)/3;
            DB X2=s+(e-s)/3*2;
            DB Y1=sqrt(L*L-X1*X1);//勾股定理计算纵截距 
            DB Y2=sqrt(L*L-X2*X2);
            DB T1=Dis(X1,Y1,-X1*Y1,B,A);//计算点到直线距离 
            DB T2=Dis(X2,Y2,-X2*Y2,B,A);
            if(T1<T2){e=X2;Ans=T2;}
            else{s=X1;Ans=T1;}
        }       
    }
    if(Ans<-eps)
        puts("My poor head =(");
    else printf("%.7lf\n",std::min(Ans,L));
    return 0;
}

save

题目

C 城所有的道路都是单向的。不同道路之间有路口,每个路口都有一个大楼。

有一天,城市里的所有大楼因为不明原因,突然着火了。作为超人的你要去拯救这些大楼。初始的时候你在 S 号楼,最后你必须到达某个有补给站的大楼,你可以沿着单向道路行驶。你可以经过某条道路或者某个大楼若干次,经过一个大楼你就可以消灭一个大楼的大火。每个大楼都有一个重要程度,最后这个任务的评价分数就是你经过的所有大楼的重要度之和(若重复经过某个大楼多次,则不重复算分)。

你是一个聪明的超人,你想知道,通过合理的规划路线,你这次任务能得到的最高得分是多少。

注意,该城市的道路可能有重边或自环。

思路

Tarjan 缩点,拓扑排序求DAG图上的最短路,时间复杂度\(O(n+m)\).

#include<bits/stdc++.h>
const int SIZE=1000005;

int n,m,head[SIZE],nex[SIZE],fro[SIZE],to[SIZE],Tot,weight[SIZE],S,p;
void Link(int u,int v)
{
    nex[++Tot]=head[u];
    head[u]=Tot;
    fro[Tot]=u;
    to[Tot]=v;
}
bool mk[SIZE];

int DFN[SIZE],Low[SIZE],Time,Sta[SIZE],Top;
int Belong[SIZE],Cnt,wx[SIZE],mkx[SIZE];
bool Ins[SIZE];

void Tarjan(int u)
{
    DFN[u]=Low[u]=++Time;
    Sta[++Top]=u;
    Ins[u]=1;
    for(int i=head[u];i;i=nex[i])
    {
        int v=to[i];
        if(!DFN[v])
        {
            Tarjan(v);
            Low[u]=std::min(Low[u],Low[v]);
        }
        else
            if(Ins[v])
                Low[u]=std::min(Low[u],DFN[v]);
    }
    if(Low[u]==DFN[u])
    {
        ++Cnt;
        do
        {
            Belong[Sta[Top]]=Cnt;
            Ins[Sta[Top]]=0;
            wx[Cnt]+=weight[Sta[Top]];
            if(mk[Sta[Top]])
                mkx[Cnt]=1;
        }while(Sta[Top--]!=u);
    }
}

int hx[SIZE],nx[SIZE],tx[SIZE],Totx,InDeg[SIZE];
void Linkx(int u,int v)
{
    nx[++Totx]=hx[u];
    hx[u]=Totx;
    tx[Totx]=v;
    ++InDeg[v];
}

long long Dis[SIZE],Ans;
std::queue<int>q;

int main()
{
    freopen("save.in","r",stdin);
    freopen("save.out","w",stdout);
    scanf("%d%d",&n,&m);
    int u,v;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        Link(u,v);
    }
    for(int i=1;i<=n;i++)scanf("%d",&weight[i]);
    scanf("%d%d",&S,&p);
    while(p--)
    {
        scanf("%d",&u);
        mk[u]=1;
    }
    for(int i=1;i<=n;i++)
    {
        if(!DFN[i])
            Tarjan(i);
    }
    for(int i=1;i<=Tot;i++)
    {
        if(Belong[fro[i]]!=Belong[to[i]])
            Linkx(Belong[fro[i]],Belong[to[i]]);
    }
    S=Belong[S];
    memset(Dis,-0x3F,sizeof(Dis));
    Dis[S]=wx[S];
    for(int i=1;i<=Cnt;i++)
    {
        if(InDeg[i]==0)
            q.push(i);
    }
    while(q.size())
    {
        int u=q.front();
        q.pop();
        for(int i=hx[u];i;i=nx[i])
        {
            int v=tx[i];
            Dis[v]=std::max(Dis[v],Dis[u]+wx[v]);
            --InDeg[v];
            if(InDeg[v]==0)
                q.push(v);
        }
    }
    for(int i=1;i<=Cnt;i++)
    {
        if(mkx[i])
            Ans=std::max(Ans,Dis[i]);
    }
    std::cout<<Ans;
    return 0;
}

2019/9/15 校内模拟赛 考试报告

原文:https://www.cnblogs.com/TaylorSwift13/p/11523386.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!