cf1282C,E

D是个交互,一看就不太想做,于是把CE写了些,C算是比较简单的遍历,E写了老半天,近期感觉自己编码能力没以前那么强了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200005
 
int n,T,a,b;
struct Node{int len,time;}p[N];
int cmp(Node a,Node b){return a.time<b.time;}
int suf1[N],suf2[N];
 
int main(){
    int t;cin>>t;
    while(t--){
        cin>>n>>T>>a>>b;
        //gthththfghhghg
        suf1[n+1]=suf2[n+1]=0;
        ll sum=0;
        for(int i=1;i<=n;i++){
            int f;scanf("%d",&f);
            if(f) p[i].len=b;
            else p[i].len=a;
            sum+=p[i].len;
        }
        for(int i=1;i<=n;i++)scanf("%d",&p[i].time);
        if(sum<=T){
            cout<<n<<'\n';
            continue;
        }
        
        sort(p+1,p+1+n,cmp);
        for(int i=n;i>=1;i--)
            if(p[i].len==a){
                suf1[i]=suf1[i+1]+1;
                suf2[i]=suf2[i+1];
            }
            else {
                suf1[i]=suf1[i+1];
                suf2[i]=suf2[i+1]+1;
            }
        
        
        ll total=0;
        int ans=0; 
        p[0].time=-1;
        for(int i=1;i<=n;i++){
            if(p[i].time==p[i-1].time){total+=p[i].len;continue;}
            
            int now=p[i].time-1;//考试时间 
            if(now<total){total+=p[i].len;continue;}
            
            int last=now-total;
            int res=i-1;
            if(last/a>suf1[i]){
                res+=suf1[i];
                last-=suf1[i]*a;
                res+=min(suf2[i],last/b);
            }
            else res+=last/a;
            ans=max(ans,res);
            total+=p[i].len;
        }
        
        cout<<ans<<'\n';
    }
}

E

/*
用分割后的多边形建图,按拓扑排序的思想,当一个结点度数为2时,它就是下一个被割掉三角形的顶点
所以先把度数是2的点进队,
拓扑排序:当前结点now,每次求出当前和其相连的两个点a,b(有且仅有两个未割掉的点和其相连),在新图上链接now-a,now-b
割掉的顶点用vis标记了 
 
新图必定是个环,最后用dfs扫描一次这个环即可 
顺便用map保存编号,ans存每次割掉三角形的编号 
*/
#include<bits/stdc++.h>
#include<map>
#include<queue>
#include<set>
#include<vector>
using namespace std;
#define N 200005
 
map<pair<int,int> ,int>mp1;
map<pair<int,pair<int,int>>, int> mp;
int n,in[N],vis[N];
set<int>E[N];
vector<int>G[N],g[N];
vector<int>ans;
vector<int>v;
 
int dfn[N];
void dfs(int x){
    dfn[x]=1;v.push_back(x);
    for(auto y:g[x])
        if(!dfn[y])dfs(y);
}
 
 
void init(){
    for(int i=1;i<=n;i++){
        dfn[i]=in[i]=vis[i]=0;
        E[i].clear();
        G[i].clear();
        g[i].clear();
    }
    ans.clear();
    v.clear();
    mp.clear();
    mp1.clear();
}
 
void add1(int u,int v){
    E[u].insert(v);E[v].insert(u);
}
void add2(int u,int v){
    G[u].push_back(v);
}
void add3(int u,int v){
    g[u].push_back(v);g[v].push_back(u);
}
 
int main(){
    int t;cin>>t;
    while(t--){
        init();
        cin>>n;
        for(int i=1;i<=n-2;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add1(a,b);add1(b,c);add1(a,c);
            mp[make_pair(a,make_pair(b,c))]=i;
            mp[make_pair(a,make_pair(c,b))]=i;
            mp[make_pair(b,make_pair(a,c))]=i;
            mp[make_pair(b,make_pair(c,a))]=i;
            mp[make_pair(c,make_pair(b,a))]=i;
            mp[make_pair(c,make_pair(a,b))]=i;
        }
        for(int i=1;i<=n;i++)
            for(auto x:E[i]){
                in[i]++;
                add2(i,x);
            }
        
        queue<int>q;
        for(int i=1;i<=n;i++)if(in[i]==2)q.push(i);
        
        int cnt=0,tot=0;
        
        while(q.size()){
            int now=q.front();q.pop();
            vis[now]=1;
            int a,b;
            for(auto x:G[now])
                if(!vis[x]){a=x;break;}
            for(auto x:G[now])
                if(!vis[x] && x!=a){b=x;break;}
            
            mp1[make_pair(a,b)]=1;
            mp1[make_pair(b,a)]=1;
            if(tot<n){
                if(!mp1[make_pair(now,a)])
                    add3(now,a),tot++;
                if(!mp1[make_pair(now,b)])
                    add3(now,b),tot++;
            }
            ans.push_back(mp[make_pair(now,make_pair(a,b))]);
            
            in[a]--;in[b]--;
            if(in[a]==2)q.push(a);
            if(in[b]==2)q.push(b);
            
            if(++cnt==n-2)break;
        }
        
        dfs(1);
    //    for(int i=1;i<=n;i++)
    //        cout<<g[i].size()<<'\n';
        for(auto x:v)cout<<x<<' ';
        puts("");
        for(auto x:ans)cout<<x<<' ';
        puts(""); 
    }    
}

posted on 2019-12-27 13:57  zsben  阅读(161)  评论(0编辑  收藏  举报

导航