机房模拟赛 2017.7.3

今天成都突然下好大的雨啊233,我和zyc跑出去在操场跑了一圈多,刚出门三秒衣服就湿透了的那种雨,完了之后我还将就在墨池里游了几圈233,墨池的水好暖和,洗了澡之后才发现没有裤子换…


暑假第二次模拟赛,考的时候浑身舒服,三十分钟做完前两道题感觉自己要AK,然后第三题就挂了,震惊的是,第一题也挂了…难受…


题目


qu


【问题描述】

给你一个操作序列,问这个维护操作序列的数据结构是哪一种?


【输入格式】

第一行是一个正整数n代表操作数目。 接下来 n行,每行两个正整数opt,v。如果opt = 1,代表我们将v加入数据结构;如果opt= 2,代表我们从数据结构中取出了一个元素,这个元素的值是v。


【输出格式】

输出三行,第一行代表数据结构是否可能是栈,第二行代表数据结构是否可 能是队列,第三行代表数据结构是否可能大根堆。每一行的结果都只可能是“YES” 或者“No”。


【样例输入】

2 1 1 2 1


【样例输出】

YES
YES
YES


【样例解释】

╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶


【数据规模与约定】

100%的数据满足1 ≤ n≤ 103。


题解:

显然直接模拟三个数据结构就可以了,我用的STL,注意两点,第一点…这点真坑,输出YES但是输出No,小写o,我就挂在这里了,还有一个要注意的是要判数据结构是否为空


AC代码

#include<cstdio>
#include<queue>
#include<stack>
#include<iostream>
#include<cstring>
using namespace std;
priority_queue<int>heapp;
queue<int>quee;
stack<int>stacc;
bool judge[10];
int n,opt,v;
int main(){
    freopen("qu.in","r",stdin);
    freopen("qu.out","w",stdout); 
    memset(judge,true,sizeof(judge));
    scanf("%d",&n);
    for(register int i=1;i<=n;i++){
        scanf("%d%d",&opt,&v);
        if(opt==1){
            heapp.push(v);
            quee.push(v);
            stacc.push(v);
        }else{
            int temp;
            if(heapp.size()==0){
                judge[3]=false;
            }else{
                temp=heapp.top();heapp.pop();
                if(temp!=v) judge[3]=false;
            }
            if(quee.size()==0){
                judge[2]=false;
            }else{
                temp=quee.front();quee.pop();
                if(temp!=v) judge[2]=false;
            }
            if(stacc.size()==0){
                judge[1]=false;
            }else{
                temp=stacc.top();stacc.pop();
                if(temp!=v) judge[1]=false;
            }
        }
        if(judge[1]==false&&judge[2]==false&&judge[3]==false) break;
    }
    for(register int i=1;i<=3;i++){
        if(judge[i]) printf("YES\n");
        else         printf("No\n");
    }
    return 0;
}

ming


【问题描述】

给你N个任务,对于第i个任务,我们需要ti的时间去完成它,它的 deadline 是di。如果我们设fi为第i个任务的完成时刻,那你需要做的便是确定每个任务的 开始时间,使得max((max(0,fi−di))最小化。(同一时间只能做一个任务)


【输入格式】

第一行一个整数N表任务的个数。 接下来N行每行两个整数,分别代表ti,di。


【输出格式】

一行一个整数代表最小化的max((max(0,fi−di))。


【样例输入】

2 1 1 2 2


【样例输出】

1


【样例解释】

╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶


【数据规模与约定】

对于30%的数据,1 ≤ N≤ 10。 对于60%的数据,1 ≤ N≤ 103。 对于100%的数据,1 ≤N≤ 105。


题解:

显然第二题可以直接贪心,sort一遍然后贪就行了


AC代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;

int readin(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
struct Line{
    int deadline,t;
}line[100000+10];
int N,tail;
bool cmp(const Line &A,const Line &B){return A.deadline<B.deadline;}
int main(){
    freopen("ming.in","r",stdin);
    freopen("ming.out","w",stdout);
    N=readin();
    int te,mp;
    for(register int i=1;i<=N;i++){
        te=readin();mp=readin();
        tail++;
        line[tail].deadline=mp;
        line[tail].t=te;
    }
    sort(line+1,line+tail+1,cmp);
    //for(register int i=1;i<=tail;i++) printf("%d\n",line[i].deadline);
    int now=0;
    int maxn=-1;
    for(register int i=1;i<=tail;i++){
        now+=line[i].t;
        maxn=max(maxn,max(0,now-line[i].deadline));
    }
    printf("%d\n",maxn);
    return 0;
}

zi


【问题描述】

我们有m+ 1棵树,分别是T0,T1,…,Tm。其中T0是一棵只有一个点的树,点 的编号为0。 生成第i棵树我们需要五个参数ai,bi,ci,di,li(ai,bi < i)。我们生成第i棵树是 将第ai棵树的ci号点和第bi棵树的di号点用一条长度为li的边连接起来形成的新 的树(不会改变原来两棵树)。下面我们需要对新树中的点重编号:对于原来在 第ai棵树中的点,我们不会改变他们的编号;对于原来在第bi棵树中的点,我们会将他们的编号加上第ai棵树的点的个数作为新的编号。 定义

F(Ti)=i=0n1j=i+1n1d(vi,vj)

其中,n为树Ti的大小,vi,vj是Ti中的点,d(vi,vj)代表这两个点的距离。现 在希望你求出∀1 ≤ i ≤ m,F(Ti)是多少。


【输入格式】

第一行一个整数m。 接下来每行五个整数ai,bi,ci,di,li代表第i棵树的生成方式。


【输出格式】

m行,每行一个整数,代表的值。


【样例输入】

3 0 0 0 0 2 1 1 0 0 4 2 2 1 0 3


【样例输出】

2 28 216


【样例解释】

╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶


【数据规模与约定】

对于30%的数据,1 ≤ m ≤ 10。 对于60%的数据,每棵树的点数个数不超过105。 对于100%的数据,1 ≤ m ≤ 60。


这道题没有那么地显然,考试的时候看到我就不想写,当时想了一种暴力建树,树链剖分暴力处理询问的方法,代码应该至少200+,而且还只能得30分,点分也不知道最多能得多少分…但朴素的各种方法都很暴力,所以当时就直接看数学去了233。这道题正解的思路是这样的

F[Ti] Ti 中每一对点的距离和, ai,bi 表示 i 树由ai,bi构成,那么有

F(Ti)=F(Tai)+F(Tbi)+|Tbi|uTaid(u,ci)+|Tai|uTbid(u,di)+|Tai||Tbi|li

其中 |Ttempi| 符号表示该数的size大小
A(Ti,u) 表示树 Ti 中所有点到 u 的距离和,D(Ti,u,v)表示树 Ti 中u到v的距离,可以得到
F(Ti)=F(Tai)+F(Tbi)+|Tbi|A(Tai,ci)+|Tai|A(Tbi,di)+|Tai||Tbi|li

然后讨论u和v的位置,进行递归的分治往下枚举,即可得到结果,其中如果我们设 uTai ,那么显然可以得到如下的结论
A(Ti,u)=A(Tai,u)+A(Tbi)+|Tbi|(li+D(Tai,ci,u))

如果两个点 u,v 同时在 ai
D(Ti,u,v)=D(Tai,u,v)

如果两个点 u,v 分别一个在 ai 中一个在 bi 中,那么满足
D(Ti,u,v)=D(Tai,u,ci)+li+D(Tbi,di,v)


AC代码

#include<cstdio>
#include<iostream>
#include<map>
#include<algorithm>
#include<utility>
using namespace std;
#define dnt long long
map<pair<int,int>,dnt> m;
map<pair<int,pair<int,int> >,dnt> d;
const int lk=1000000000+7;
long long size[100],ans[100];
struct order{
    int a,b,c,d,l;
}order[100];
dnt D(dnt i,dnt u,dnt v){//计算Ti中u到v的距离 
    if(i==0||u==v) return 0;
    map<pair<int,pair<int,int> >,dnt>::iterator it=d.find(make_pair(i,make_pair(u,v)));
    if(it!=d.end()) return it->second;
    dnt temp=0;
    bool left_u=(u<size[order[i].a]),left_v=(v<size[order[i].a]);
    if(left_u&&left_v) temp=D(order[i].a,u,v);
    if(!left_u&&!left_v) temp=D(order[i].b,u-size[order[i].a],v-size[order[i].a]);
    if(left_u&&!left_v) temp=(D(order[i].a,u,order[i].c)+order[i].l+D(order[i].b,v-size[order[i].a],order[i].d))%lk;
    if(!left_u&&left_v) temp=(D(order[i].a,v,order[i].c)+order[i].l+D(order[i].b,u-size[order[i].a],order[i].d))%lk;
    d[make_pair(i,make_pair(u,v))]=temp;
    return temp;
}
dnt A(dnt i,dnt u){
    if(i==0) return 0;
    pair<int,int>p(i,u);
    map<pair<int,int>,dnt>::iterator it=m.find(p);
    if(it!=m.end()) return it->second;
    if(u<size[order[i].a]) m[p]=((A(order[i].a,u)+A(order[i].b,order[i].d))%lk+size[order[i].b]*(order[i].l+D(order[i].a,u,order[i].c)))%lk;
    else m[p]=(A(order[i].b,u-size[order[i].a])+(size[order[i].a]*(D(order[i].b,u-size[order[i].a],order[i].d)+order[i].l)%lk)%lk+A(order[i].a,order[i].c))%lk;
    return m[p];
}
dnt F(dnt Ti,dnt Tai,dnt Tbi,dnt ci,dnt di,dnt li){
    ans[Ti]=(ans[Tai]+ans[Tbi])%lk+(A(Tai,ci)*size[Tbi])%lk+(A(Tbi,di)*size[Tai])%lk+((size[Tai]*size[Tbi])%lk*li)%lk;
    ans[Ti]%=lk;
    return ans[Ti];
}
int main(){
    freopen("zi.in","r",stdin);
    freopen("zi.out","w",stdout);
    size[0]=1;
    int m;
    scanf("%d",&m);
    for(register int i=1;i<=m;i++){
        scanf("%d%d%I64d%I64d%I64d",&order[i].a,&order[i].b,&order[i].c,&order[i].d,&order[i].l);
        size[i]=(size[order[i].a]+size[order[i].b])%lk;
        cout<<F(i,order[i].a,order[i].b,order[i].c,order[i].d,order[i].l)<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: three.js是一种用于创建和呈现3D图形的JavaScript库。它使用WebGL技术来实现硬件加速渲染,并且非常适合创建交互式的3D场景。对于创建3D机房场景,我们可以使用three.js来展示机房的各个部分和设备。 首先,我们可以使用three.js创建一个场景,并在其内部添加各种元素,例如机柜、服务器、网络设备等。通过three.js的3D坐标系,我们可以精确放置和定位每个元素,以便它们在场景中正确地呈现。 接下来,我们可以使用three.js的光照和材质系统来给机房场景添加逼真的光影效果。通过在适当的位置放置光源,我们可以模拟机房内不同灯光的亮度和颜色。同时,我们可以使用各种材质来给每个元素赋予适当的外观和质感,使其看起来更加真实。 此外,我们可以借助three.js的动画功能来创建机房环境中的动态效果。例如,我们可以让风扇旋转、数据线闪烁或者服务器指示灯闪烁等。利用three.js的动画功能,我们可以为机房场景添加更多的生动感和交互性。 最后,我们可以结合three.js的控制器和交互功能来实现用户与机房场景的互动。通过添加旋转、缩放和平移等交互式控制器,用户可以自由地浏览和探索机房的各个角落。此外,我们还可以添加鼠标点击和触摸事件,以便用户可以与元素进行交互,例如点击服务器获取详细信息或者切换设备状态等。 总之,使用three.js可以轻松地创建一个3D机房场景,以展示机房设备和环境。通过其丰富的功能和易于使用的接口,我们可以打造一个逼真、交互性强的3D机房展示应用。 ### 回答2: three.js是一款开源的JavaScript 3D图形库,可用于创建Web上的交互式3D场景。通过使用three.js,我们可以很容易地在网页上创建一个虚拟的3D机房。 首先,我们需要使用three.js创建一个3D场景。我们可以设置一个适应页面大小的渲染器,并创建一个相机和光源,以便在场景中投射阴影和照明。然后,我们可以通过加载3D模型文件或手动创建物体来创建机房中的各种设备和家具。 在机房的设计中,我们可以添加机柜、服务器、交换机、路由器、电视屏幕等设备。我们可以使用three.js提供的几何体对象或者加载外部的3D模型文件,将它们添加到场景中,并设置各种材质和纹理以使它们更加逼真。 除了设备和家具外,我们还可以添加交互元素,例如按钮、滑块和下拉菜单,以控制机房内的设备或演示不同的场景。我们可以使用three.js提供的鼠标和键盘事件来监听用户的交互动作,并通过相应的代码控制场景中的元素。 最后,我们可以为机房中的设备和家具创建动画效果。在three.js中,我们可以通过改变物体的位置、旋转和缩放来实现动画效果。我们可以为设备的运行状态创建动画,并使用three.js的渐变和缓动函数来实现平滑过渡效果。 通过使用three.js创建一个3D机房,我们可以在网页上以全新的方式展示和交互机房设计。用户可以通过鼠标和键盘控制设备、改变场景,并观察设备的运行状态。three.js提供了丰富的功能和易用的API,使得创建和展示3D机房设计变得简单而有趣。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值