首页 > 其他 > 详细

2019/2/28 考试记录

时间:2019-02-28 21:50:23      阅读:120      评论:0      收藏:0      [点我收藏+]

状态差得一批。。

T1

传送门

解题思路

  考试时想写\(60\)写挂。正解就是用堆把洗衣服的和晾衣服的贪心选一遍,求出每个衣服的最短时间,然后合并时就拿最大的和最小的,次大的和次小的依次合并取\(max\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>

using namespace std;
const int N=100005;
typedef long long LL;

inline int rd(){
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    return f?x:-x;
}

int n,m,l,w[N],d[N];
LL t1[N],t2[N],ans;
struct Node{
    int id; LL w;
    friend bool operator<(const Node A,const Node B){
        return A.w>B.w;
    }
    Node(int _id=0,LL _w=0) {id=_id; w=_w;}
};
priority_queue<Node> Q;

int main(){
    l=rd(),n=rd(),m=rd(); Node now;
    for(int i=1;i<=n;i++) w[i]=rd(),Q.push(Node(i,1ll*w[i]));
    for(int i=1;i<=l;i++){
        now=Q.top(); Q.pop();
        t1[i]=now.w; Q.push(Node(now.id,now.w+w[now.id]));
    }
    while(Q.size()) Q.pop();
    for(int i=1;i<=m;i++) d[i]=rd(),Q.push(Node(i,1ll*d[i]));
    for(int i=1;i<=l;i++){
        now=Q.top(); Q.pop();
        t2[i]=now.w; Q.push(Node(now.id,now.w+d[now.id]));
    }   
    for(int i=1;i<=l;i++) ans=max(ans,t1[i]+t2[l-i+1]);
    printf("%lld\n",ans);
    return 0;
}

T2

传送门

解题思路

  考场上暴搜\(20\)分。这个需要模型转化,首先说\(50\)分的做法,就是对于一个串来说,把它拆成两个,如果没有\('?'\)就拆成两个一样的,有的话拆的两个串一个把问号视作\(0\),一个视作\(1\),然后插到\(Trie\)树上。可以发现\(Trie\)树上一个节点和它的祖先不能同时存在,那么就转化成了个\(2-sat\)问题,可以暴力在树上跳,然后连边后\(2-sat\)判断,但这样连边边数过多,所以只有\(50\)分。而发现这样建边有好多无用的边,我们可以考虑优化连边,对于一个\(Trie\)上的点,我们可以把在这个点结束的串合并起来,然后建一个\(in\)\(out\),而对于\(2-sat\)里的边,发现对于一个点来说,它要连的其实就是这个节点中除自己的其他边,可以维护一个前缀后缀点的集合,这样边的数量就便少很多。

50分代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>

using namespace std;
const int N=1000005;

int n,head[N],cnt,to[N<<1],nxt[N<<1],pos[N];
char s[N];
vector<int> v[N];

void add(int bg,int ed){
//  cout<<bg<<" "<<ed<<endl;
    to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
}

struct Trie{
    int ch[N][2],fa[N],tot=1;
    void build(int id){
        scanf("%s",s+1); int now=1,len=strlen(s+1);
        for(int i=1;i<=len;i++){
            if(s[i]=='?' || s[i]=='1') {
                if(ch[now][1]) now=ch[now][1];
                else ch[now][1]=++tot,fa[tot]=now,now=tot;
            }
            else {
                if(ch[now][0]) now=ch[now][0];
                else ch[now][0]=++tot,fa[tot]=now,now=tot;
            }
        } v[now].push_back(id); pos[id]=now; now=1;
        for(int i=1;i<=len;i++){
            if(s[i]=='1') {
                if(ch[now][1]) now=ch[now][1];
                else ch[now][1]=++tot,fa[tot]=now,now=tot;
            }
            else {
                if(ch[now][0]) now=ch[now][0];
                else ch[now][0]=++tot,fa[tot]=now,now=tot;  
            }
        }
        v[now].push_back(id+n); pos[id+n]=now;
    }
    void solve(int id){
        int now=pos[id],tmp;
        while(now!=1){
            for(int i=0;i<v[now].size();i++){
                tmp=v[now][i];
                if(tmp==id || tmp==id+n) continue;
                add(id,(tmp>n?tmp-n:tmp+n));
                add(tmp,(id>n?id-n:id+n));
            }
            now=fa[now];
        }   
    }
}trie;

int dfn[N],low[N],num,stk[N],top,col[N],col_num;
bool vis[N];

void tarjan(int x){
    dfn[x]=low[x]=++num; 
    stk[++top]=x; vis[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        int u=to[i]; 
        if(!dfn[u]) tarjan(u),low[x]=min(low[x],low[u]);
        else if(vis[u]) low[x]=min(low[x],dfn[u]);
    }
    if(low[x]!=dfn[x]) return;
    col[x]=++col_num; vis[x]=0;
    while(stk[top]!=x){
        vis[stk[top]]=0;
        col[stk[top--]]=col_num;
    } top--;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) trie.build(i);
    for(int i=1;i<=2*n;i++) trie.solve(i);
    for(int i=1;i<=2*n;i++) if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;i++)
        if(col[i]==col[i+n]) {puts("NO"); return 0;}
    puts("YES");
    return 0;
}

100分代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>

using namespace std;
const int N=3000005;

int n,head[N],cnt,to[N<<3],nxt[N<<3],pos[N];
char s[N];
vector<int> v[N];

void add(int bg,int ed){
    to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
}

inline int work(int id) {return id<=n?id+n:id-n;}

struct Trie{
    int ch[N][2],fa[N],tot=1,in[N],out[N];
    void build(int id){
        scanf("%s",s+1); int now=1,len=strlen(s+1);
        for(int i=1;i<=len;i++){
            if(s[i]=='?' || s[i]=='1') {
                if(ch[now][1]) now=ch[now][1];
                else ch[now][1]=++tot,fa[tot]=now,now=tot;
            }
            else {
                if(ch[now][0]) now=ch[now][0];
                else ch[now][0]=++tot,fa[tot]=now,now=tot;
            }
        } v[now].push_back(id); now=1;
        for(int i=1;i<=len;i++){
            if(s[i]=='1') {
                if(ch[now][1]) now=ch[now][1];
                else ch[now][1]=++tot,fa[tot]=now,now=tot;
            }
            else {
                if(ch[now][0]) now=ch[now][0];
                else ch[now][0]=++tot,fa[tot]=now,now=tot;  
            }
        }
        v[now].push_back(id+n);
    }
    void solve(){
        int tmp=tot; tot=n+n;
        for(int i=2;i<=tmp;i++){
            if(v[i].size()==0) continue;
            in[i]=++tot; out[i]=++tot;
            for(int j=0;j<v[i].size();j++){
                int x=v[i][j],y=work(v[i][j]);
                for(int k=fa[i];k;k=fa[k])
                    if(in[k]) add(in[k],y),add(x,out[k]);
                add(x,in[i]); add(out[i],y);
            }
            static int w[N];
            for(int j=0;j<v[i].size();j++){
                int x=v[i][j]; w[j]=++tot;
                if(j) add(w[j],w[j-1]);
                add(w[j],work(x));
                int t=j-1;
                if(j && work(x)==v[i][j-1]) t--;
                if(t>=0) add(x,w[t]);
            }
            int num=v[i].size()-1;
            for(int j=num;j>=0;j--){
                int x=v[i][j]; w[j]=++tot;
                if(j<num) add(w[j],w[j+1]);
                add(w[j],work(x)); 
                int t=j+1;
                if(j<v[i].size()-1 && work(x)==v[i][j+1]) t++;
                if(t<v[i].size()) add(x,w[t]);
            }
        }   
    }   
}trie;

int dfn[N],low[N],num,stk[N],top,col[N],col_num;
bool vis[N];

void tarjan(int x){
    dfn[x]=low[x]=++num; 
    stk[++top]=x; vis[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        int u=to[i]; 
        if(!dfn[u]) tarjan(u),low[x]=min(low[x],low[u]);
        else if(vis[u]) low[x]=min(low[x],dfn[u]);
    }
    if(low[x]!=dfn[x]) return;
    col[x]=++col_num; vis[x]=0;
    while(stk[top]!=x){
        vis[stk[top]]=0;
        col[stk[top--]]=col_num;
    } top--;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) trie.build(i);
    trie.solve();
    for(int i=1;i<=trie.tot;i++) if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;i++)
        if(col[i]==col[i+n]) {puts("NO"); return 0;}
    puts("YES");
    return 0;
}

T3

咕咕咕

2019/2/28 考试记录

原文:https://www.cnblogs.com/sdfzsyq/p/10453089.html

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