2018 BUPT Winter Training #4 Div.2

17 篇文章 0 订阅
12 篇文章 0 订阅

A - Stall Reservations

最小堆维护畜栏的工作区间即可。

#include <cstdio>
#include <queue>
#include <algorithm>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
using namespace std;
struct cow{
    int a,b,id,stall;
    bool operator<(const cow y)const{return b>y.b;}
}P[50005];
bool cmp1(cow x,cow y){
    return x.a<y.a;
}
bool cmp2(cow x,cow y){
    return x.id<y.id;
}
priority_queue<cow> q;
int main(){
    int n;
    while(~scanf("%d",&n)){
        F(i,n){
            scanf("%d%d",&P[i].a,&P[i].b);
            P[i].id=i;
        }
        sort(P,P+n,cmp1);
        int stall=1;
        P[0].stall=1;
        q.push(P[0]);
        cow top;
        FF(i,1,n-1){
            top=q.top();
            if(P[i].a>top.b){
                P[i].stall=top.stall;
                q.pop();
                q.push(P[i]);
            }else {
                P[i].stall=++stall;
                q.push(P[i]);
            }
        }
        sort(P,P+n,cmp2);
        printf("%d\n",stall);
        F(i,n)printf("%d\n",P[i].stall);
    }
}

B - ACboy needs your help again!

栈裸题…栈裸题也是才能。

#include <cstdio>
#include <queue>
#include <stack>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
using namespace std;
char o[10];
queue<int> q;
stack<int> s;
int main(){
    int t,n,num;
    scanf("%d",&t);
    while(t--){
        scanf("%d%s",&n,o);
        if(o[2]=='F'){
            while(!q.empty())q.pop();
            F(i,n){
                scanf("%s",o);
                if(o[0]=='I'){
                    scanf("%d",&num);
                    q.push(num);
                }
                else {
                    if(q.empty())printf("None\n");
                    else printf("%d\n",q.front()),q.pop();
                }
            }
        }else{
            while(!s.empty())s.pop();
            F(i,n){
                scanf("%s",o);
                if(o[0]=='I'){
                    scanf("%d",&num);
                    s.push(num);
                }else {
                    if(s.empty())printf("None\n");
                    else printf("%d\n",s.top()),s.pop();
                }
            }
        }
    }
}

C - Train Problem I HDU - 1022

贪心地弹出栈顶元素,最后也不能完成目标字符串就算失败了。

#include <iostream>
#include <cstring>
#include <string>
#include <stack>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
using namespace std;
string s1,s2;
bool ans_with_o[25];

int main(){
    int n;
    ios::sync_with_stdio(false);
    while(cin>>n>>s1>>s2){
        stack<char> s;
        int cur=0,pi=0,len=n<<1;
        F(i,n){
            s.push(s1[i]);
            ans_with_o[cur++]=0;
            while(pi<n&&!s.empty()){
                if(s.top()==s2[pi]){
                    pi++;
                    ans_with_o[cur++]=1;
                    s.pop();
                }else break;
            }
        }
        if(s.empty()){
            cout<<"Yes."<<endl;
            F(i,len)if(ans_with_o[i])cout<<"out\n";else cout<<"in\n";
            cout<<"FINISH"<<endl;
        }
        else cout<<"No.\nFINISH\n";
    }
}

D - 简单计算器

利用栈模拟运算优先级。话说我写了个自动机本地运行造了无数数据一点问题都没有,但提交就WA了…最近一老出这种状况…

#include <cstdio>
#include <stack>
using namespace std;
stack <double> exp;
int main() {
    char c;
    double a,b,ans=0;
    while(~scanf("%lf",&a)){
        c=getchar();
        if(c=='\n'&& a == 0)break;
        exp.push(a);
        c=getchar();
        while(~scanf("%lf",&b)){
            switch(c){
                case '*':
                    a=exp.top();exp.pop();
                    exp.push(a * b);
                    break;
                case '/':
                    a=exp.top();exp.pop();
                    exp.push(a/b);
                    break;
                case '+':
                    exp.push(b);
                    break;
                case '-':
                    exp.push(-b);
                    break;
            }
            c=getchar();
            if(c=='\n')break;
            c=getchar();
            getchar();
        }
        ans=0;
        while(!exp.empty())ans+=exp.top(),exp.pop();
        printf("%.2lf\n",ans);
    }
}

E - 程序自动分析

并查集裸题。使拥有相同根的元素拥有相同的值。

#include <cstdio>
#include <vector>
#include <map>
#include <utility>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--)
#define PB push_back
#define MP make_pair
#define sec second
#define fir first
using namespace std;
typedef long long ll;
ll pre[1000010];
map<int,int> p;
int find(int x){
    return x==pre[x]?x:pre[x]=find(pre[x]);
}
typedef pair<int,int> pii;
vector <pii> neq;
int main(){
    int t,n,a,b,e,flag,bi;
    scanf("%d",&t);
    while(t--){
        F(i,1000010)pre[i]=i;
        p.clear();
        neq.clear();
        flag=bi=1;
        scanf("%d",&n);
        F(i,n){
            scanf("%d%d%d",&a,&b,&e);
            if(p[a])a=p[a];
            else p[a]=++bi,a=bi;
            if(p[b])b=p[b];
            else p[b]=++bi,b=bi;
            if(e==1){
                a=find(a);b=find(b);
                if(a!=b)pre[a]=b;
            }else neq.PB(MP(a,b));
        }
        TRV(i,neq){
            if(find(neq[i].fir)==find(neq[i].sec)){
                flag=0;
                break;
            }
        }
        if(flag)printf("YES\n");
        else printf("NO\n");
    }
}

F - 齿轮

并查集,维护与根的相对转速。(自己写的又是无限wa,绝望orz)

#include <cstdio>
#include <cstdlib>
#include <cmath> 
#include <cstring>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
#define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--)
const double eps=1e-7;
inline double sgn(double x){
    return (fabs(x)>=eps)*x;
}
double rate[1005];
int pre[1005];
inline void init(int n){
    for(int i=1;i<=n;i++)rate[pre[i]=i]=1.0;
}
inline int find(int x){
    if(x==pre[x])return x;
    int u=pre[x];
    pre[x]=find(pre[x]);
    rate[x]*=rate[u];
    return pre[x];
}
int main(){
    int t,T,N,M,u,v,x,y,a,b;
    double Rate;bool flag;
    scanf("%d",&T);
    FF(t,1,T){
        flag=1;
        scanf("%d%d",&N,&M);
        init(N);
        F(i,M){
            scanf("%d%d%d%d",&u,&v,&x,&y);
            if(flag){
                Rate=(double)y/x;
                a=find(u);b=find(v);
                if(a==b){
                    if( fabs(rate[v]-rate[u]*Rate)>eps)flag=0;
                }
                else{
                    pre[b]=a;
                    rate[b]=rate[u]*Rate/rate[v];
                }
            }
        }
        printf("Case #%d: %s\n",t,flag?"Yes":"No");
    }
}

G - 操作系统

堆维护优先级和入队时间。这道题卡cin…(ios::sync_with_stdio(0)也不行)..之前无限RE找不出哪里溢出啥的,把cin换成scanf就过了…就过了…

#include <cstdio>
#include <queue>
using namespace std;
struct pro{
    int a,t,id,pri;
    bool operator<(const pro y)const { if (pri!=y.pri)return y.pri>pri;return y.a<a; }
};
priority_queue<pro> q;
int main(){
    int t;pro top,P;
    while(~scanf("%d%d%d%d",&P.id,&P.a,&P.t,&P.pri)){
        while(t<P.a&&!q.empty()){
            top=q.top();q.pop();
            if (P.a-t>=top.t)printf("%d %d\n",top.id,t=t+top.t);
            else {
                top.t-=P.a-t;
                q.push(top);
                break;
            }
        }
        t=P.a;
        q.push(P);
    }
    while (!q.empty()) {
        pro top=q.top();q.pop();
        printf("%d %d\n",top.id,t=t+top.t);
    }
}

H - 敌兵布阵

线段树裸题…不解释了…

#include <stdio.h>
#define MAXN 50000
struct segtree{
    int l,r,s;
}sgt[(MAXN<<2)+5];
int orig[MAXN+5];
void bui(int pos,int l,int r){
    sgt[pos].l=l;sgt[pos].r=r;
    if(sgt[pos].l==sgt[pos].r){sgt[pos].s=orig[r];}
    else{
        int m=(sgt[pos].l+sgt[pos].r)>>1,lc=pos<<1;
        bui(lc,l,m);bui(lc+1,m+1,r);
        sgt[pos].s=sgt[lc].s+sgt[lc+1].s;
    }
}
void upd(int pos,int aim,int val){
    sgt[pos].s+=val;
    if(sgt[pos].l==sgt[pos].r)return ;
    int m=(sgt[pos].l+sgt[pos].r)>>1,lc=pos<<1;
    if(aim>m)upd(lc+1,aim,val);
    else upd(lc,aim,val);
}
int que(int pos,int a,int b){
    if(b<sgt[pos].l||sgt[pos].r<a)return 0;
    if(sgt[pos].l==a&&b==sgt[pos].r)return sgt[pos].s;
    int m=(sgt[pos].l+sgt[pos].r)>>1,lc=pos<<1;
    if(b<=m)return que(lc,a,b);
    if(m<a)return que(lc+1,a,b);
    return que(lc,a,m)+que(lc+1,m+1,b);
}
int main(){
    int t,n,a,b,i,j;char ope[10];
    scanf("%d",&t);
    for(i=1;i<=t;i++){
        scanf("%d",&n);
        printf("Case %d:\n",i);
        for(j=1;j<=n;j++)scanf("%d",&orig[j]);
        bui(1,1,n);
        while(scanf("%s",ope)==1){
            if(ope[0]=='E')break;
            scanf("%d%d",&a,&b);
            if(ope[0]=='A')upd(1,a,b);
            if(ope[0]=='S')upd(1,a,-b);
            if(ope[0]=='Q')printf("%d\n",que(1,a,b));
        }
    }
}

I - 宠物收养所

有序集合裸题。当然如果不用set,我们还能想到它的经典数据结构底层:平衡树,如红黑树,如splay。

#include <cstdio>
#include <set>
#include <queue>
#define INTMAX 0x7fffffff
#define mod 1000000
#define MO 1061109567
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
typedef long long ll;
using namespace std;
inline int readi(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
set<int> PQ;
int main(){
    PQ.insert(INTMAX);PQ.insert(-INTMAX);
    int n,a,v,ans=0,jPQ;
    set<int>::iterator l,r;
    n=readi();
    while(n--) {
        a=readi();v=readi();
        if(PQ.size()==2||jPQ==a)jPQ=a,PQ.insert(v);
        else {
            l=--PQ.lower_bound(v);r=PQ.lower_bound(v);
            if(*r-v>=v-*l&&*l!=-INTMAX){
                ans=(ans+v-*l)%mod;
                PQ.erase(l);
            }else{
                ans=(ans+*r-v)%mod;
                PQ.erase(r);
            }
        }
    }
    printf("%d\n",ans);
}

J - Babaei and Birthday Cake

有序集合+贪心。自己写了个splay没过…

#include <cstdio>
#include <cmath>
#include <map>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
#define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--)
#define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--)
#define all(x) x.begin(),x.end()
using namespace std;
const double PI = acos(-1.0);
typedef long long ll;
map<ll,ll> Smap;
int main(){
    map<ll,ll>::iterator it,it2;
    int n,R,H;
    ll S,outS;
    scanf("%d",&n);
    Smap[0]=0;
    FF(i,1,n){
        scanf("%d%d",&R,&H);
        S=(ll)R*R*H;
        it=Smap.lower_bound(S);
        it2=it--;
        outS=it->second+S;
        while(it2!=Smap.end()&&it2->second<=outS)it2++;
        Smap.erase(++it,it2);
        Smap[S]=outS;
    }
    printf("%.12lf",PI*(--Smap.end())->second);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值