• LOJ2984[WC2019]远古计算机(构造)


    神仙造计算机题。。。计算机造计算机

    subtask 1:

    理解了这个题的应该都能写出来。

    node 1
    read 0 a
    write a 0

    subtask 2:

    看到只有一个计算机,内存还只有两个数就明显不能真算了,打表出斐波那契数列,注意要求周期尽量少,所以应该用jmp语句来打表。

     1 node 1
     2 read 0 a
     3 add a 4
     4 jmp a
    //可以对照行号看一下,a+4行对应的就是相应的第a项
    5 write 0 0 6 write 1 0 7 write 1 0 8 write 2 0 9 write 3 0 10 write 5 0 //自己动手丰衣足食 49 write 701408733 0

    subtask 3:

    在图上bfs,找出1到n的路径,构造即可。

    bfs:

    #include<cstdio>
    #include<queue>
    using namespace std;
    int G[105],to[250],nxt[250],sz=0,pre[105],st[105],sl=-1;
    bool vis[205];
    queue<int> Q;
    inline void add(int u,int v){
        to[++sz]=v;nxt[sz]=G[u];G[u]=sz;
        to[++sz]=u;nxt[sz]=G[v];G[v]=sz;
    }
    int main(){
        freopen("oldcomputer3.in","r",stdin);
        freopen("bfs_res.out","w",stdout);
        int n,m,i,u,v;
        bool ok=0;
        scanf("%d%d%d",&i,&n,&m);
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        vis[1]=1;Q.push(1);
        while(!Q.empty()&&!ok){
            u=Q.front();Q.pop();
            for(i=G[u];i;i=nxt[i])if(!vis[v=to[i]]){
                pre[v]=u;
                if(v==n){ok=1;break;}
                vis[v]=1;
                Q.push(v);
            }
        }
        for(;pre[v];v=pre[v])st[++sl]=v;
        puts("1");
        while(sl>=0)printf("%d\n",st[sl--]);
        return 0;
    }
    View Code

    构造:(其实两个完全可以写在一起,懒得改了)

    #include<cstdio>
    int a[105];
    int main(){
        freopen("bfs_res.out","r",stdin);
        freopen("oldcomputer3.out","w",stdout);
        int i,x,m=0;
        while(scanf("%d",&x)==1)a[++m]=x;
        for(i=1;i<=m;++i)printf("node %d\nread %d a\nwrite a %d\n",a[i],a[i-1],a[i+1]);
        return 0;
    }
    View Code

    subtask 4:

    从51~100号点往回跑最短路,可以发现1~50号点的距离都不超过3,这就提示我们可以根据距离递减来构造方案。

    然而dfs构造的方案只能拿60%的分,周期太多了,于是我们乱搞一下:对于每个中转,记录下它之前有几个点,每个结点输出的时候贪心地选前面结点最少的中转先输出就AC了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    int G[1005],to[4000],nxt[4000],sz=0,d[1005],n;
    queue<int> Q;
    struct opt{
        int r,w,t;
        opt(){}
        opt(int r,int w,int t):r(r),w(w),t(t){}
    };
    vector<opt> V[1005];
    inline bool cmp(opt a,opt b){return a.t<b.t;}
    inline void add(int u,int v){
        to[++sz]=v;nxt[sz]=G[u];G[u]=sz;
        to[++sz]=u;nxt[sz]=G[v];G[v]=sz;
    }
    void dfs(int u,int fa,int t){
        if(u>50&&u<=100){
            V[u].push_back(opt(fa,0,t));
            return;
        }
        int i,v;
        for(i=G[u];i;i=nxt[i])if(d[v=to[i]]==d[u]-1&&V[v].size()<3){
            V[u].push_back(opt(fa,v,t));
            dfs(v,u,t+1);
            return;
        }
    }
    int main(){
        freopen("oldcomputer4.in","r",stdin);
        freopen("oldcomputer4.out","w",stdout);
        int m,i,j,u,v;
        scanf("%d%d%d",&i,&n,&m);
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        memset(d,0x3f,sizeof(d));
        for(i=51;i<=100;++i){
            d[i]=0;
            Q.push(i);
        }
        while(!Q.empty()){
            u=Q.front();Q.pop();
            for(i=G[u];i;i=nxt[i])if(d[v=to[i]]==0x3f3f3f3f){
                d[v]=d[u]+1;
                Q.push(v);
            }
        }
        for(i=1;i<=50;++i)dfs(i,0,0);
        for(i=1;i<=1000;++i)if(!V[i].empty()){
            printf("node %d\n",i);
            sort(V[i].begin(),V[i].end(),cmp);
            for(j=0;j<V[i].size();++j)printf("read %d a\nwrite a %d\n",V[i][j].r,V[i][j].w);
        }
        return 0;
    }
    View Code

    subtask 5:

    这回要认真一点乱搞了。。。用$used_{u,t}$记下$u$在$t$时刻是不是有事做,那么$v$开始中转的时间$d_v$定为最小的$t$使得$t>d_u$且$used_{v,t}$,$used_{v,t+1}$均为$false$。跑10次$Dijkstra$即可。

    事实证明邻接表存图60%,vector存图100%,实在不放心可以random_shuffle一下。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    int d[105],pre[105];
    bool used[105][25];
    vector<int> G[105];
    struct node{
        int p,d;
        node(){}
        node(int p,int d):p(p),d(d){}
        inline bool operator <(const node &b)const{return d>b.d;}
    };
    priority_queue<node> Q;
    struct opt{
        int r,w,t;
        opt(){}
        opt(int r,int w,int t):r(r),w(w),t(t){}
    };
    vector<opt> V[105];
    inline bool cmp(opt a,opt b){return a.t<b.t;}
    inline void dijkstra(int s,int t){
        int i,u,v,dis=1,lst=0;
        node h;
        memset(d,0x3f,sizeof(d));
        while(!Q.empty())Q.pop();
        while(used[s][dis]||used[s][dis+1])++dis;
        Q.push(node(s,d[s]=dis));
        while(!Q.empty()){
            h=Q.top();Q.pop();
            if(d[u=h.p]!=h.d)continue;
            if(u==t)break;
            for(i=0;i<G[u].size();++i){
                v=G[u][i];dis=d[u]+1;
                while(used[v][dis]||used[v][dis+1])++dis;
                if(dis<d[v]){
                    pre[v]=u;
                    Q.push(node(v,d[v]=dis));
                }
            }
        }
        v=t;
        while(v!=s){
            used[v][d[v]]=used[v][d[v]+1]=1;
            V[v].push_back(opt(pre[v],lst,d[v]));
            v=pre[lst=v];
        }
        used[s][d[s]]=used[s][d[s]]=1;
        V[s].push_back(opt(0,lst,d[s]));
    }
    int main(){
        freopen("oldcomputer5.in","r",stdin);
        freopen("oldcomputer5.out","w",stdout);
        int n,m,i,j,u,v;
        scanf("%d%d%d",&i,&n,&m);
        while(m--){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        for(i=1;i<=10;++i)dijkstra(i,101-i);
        for(i=1;i<=100;++i)if(!V[i].empty()){
            printf("node %d\n",i);
            sort(V[i].begin(),V[i].end(),cmp);
            for(j=0;j<V[i].size();++j)printf("read %d a\nwrite a %d\n",V[i][j].r,V[i][j].w);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    祭蟑螂文
    端午随笔
    有感于一个用户的留言
    jQuery UI dialog插件出错信息:$(this).dialog is not a function
    @@ERROR, BEGIN TRY/CATCH and XACT_ABORT
    检索 COM 类工厂中 CLSID 为{0002450000000000C000000000000046} 的组件时失败,原因是出现以下错误: 80070005。
    【SSB】使用命令行来检测Broker是否正常通信
    C#保留2位小数总结
    引用了混乱的组件或类库可能会导致WCF代理类无法正确生成
    [转]从属性赋值到MVVM模式详解
  • 原文地址:https://www.cnblogs.com/sunshine-chen/p/11364856.html
Copyright © 2020-2023  润新知