• 「WC2019」远古计算机


    description

    传送门

    solution

    这是一道五合一的提交答案题。

    题面非常恐怖,一大段规则指令,其实有用的只有几个,只用看懂题就不慌了

    Subtask 1

    即使没看懂题也能完成这一\(Subtask\),只需要三行:

    node 1
    read 0 a
    write a 0
    

    Subtask 2

    只有2个储存单元,因此现场计算斐波那契数比较困难。注意到这样一个条件:\(k\)项不超过 \(10^9\),事实上斐波那契数的第\(45\)项就已经超过\(10^9\),因此可以想到打表,注意到题目中有这样一个操作:

    • jmp val跳转到整个程序第 val 条语句,语句从程序开头开始,用从\(1\)开始的正整数计数;

    因此直接打表输出,\(jmp\)到对应行即可,这里是生成答案的代码:

    #include<bits/stdc++.h>
    using namespace std;
    int f[51];
    int main(){
        freopen("oldcomputer2.out","w",stdout);
        puts("node 1");
        puts("read 0 a");
        puts("add a 4");
        puts("jmp a");
        f[0]=0;f[1]=1;
        for(int i=2;i<=44;++i) f[i]=f[i-1]+f[i-2];
        for(int i=0;i<=44;++i) printf("write %d 0\n",f[i]);
    	return 0;
    }
    

    Subtask 3

    要求将数从\(1\)传到\(n\)

    我们需要知道轮数尽量少意味着什么:每个点传输信息都会需要一轮时间,我们需要轮数尽量少

    因此我们直接\(bfs\)一条从\(1\)\(n\)的最短路径即可

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    int t,n,m,first[N],ru[N],cnt,First[N],Cnt;
    struct node{
    	int v,nxt;
    }e[N<<1],E[N<<1];
    inline void add(int u,int v){
    	e[++cnt].v=v;e[cnt].nxt=first[u];first[u]=cnt;
    }
    int vis[N],last[N];
    inline void bfs(int s,int t){
    	queue<int>q;
    	memset(vis,0,sizeof(vis));
    	q.push(s);vis[s]=1;
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=first[u];i;i=e[i].nxt){
    			int v=e[i].v;
    			if(!vis[v]){
    				last[v]=u;
    				vis[v]=1;
    				q.push(v);
    			}
    		}
    	}
    	int from=0,now=t;
    	while(now){
    		printf("node %d\n",now);
    		printf("read %d a\n",last[now]);
    		printf("write a %d\n",from);
    		from=now;now=last[now];
    	}
    }
    int b[N],U[N],V[N];
    int main(){
    	freopen("oldcomputer3.in","r",stdin);
    	freopen("oldcomputer3.out","w",stdout);
    	scanf("%d%d%d",&t,&n,&m);
    	for(int i=1,u,v;i<=m;++i){
    		scanf("%d%d",&u,&v);
    		add(u,v);add(v,u);
    	}
    	bfs(1,n);
    	return 0;
    }
    

    Subtask 4

    \(51-\)\(100\)号点作为源点往回跑最短路,然后从\(1-50\)号点开始,不断将身上的所有信息传递到在最短路中更改自己\(dis\)的点即可,注意一个点可能会收到多条信息,因此额外维护一个时间戳,按顺序输出即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2010;
    int t,n,m,first[N],ru[N],cnt,First[N],Cnt;
    struct node{
    	int v,nxt;
    }e[N<<1],E[N<<1];
    inline void add(int u,int v){
    	e[++cnt].v=v;e[cnt].nxt=first[u];first[u]=cnt;
    }
    int vis[N],last[N],dis[N];
    vector<pair<int,int> >ve[N];
    inline void SPFA(){
    	queue<int>q;
    	memset(vis,0,sizeof(vis));
    	memset(dis,0x3f,sizeof(dis));
    	for(int i=51;i<=100;++i)
    		q.push(i),vis[i]=1,dis[i]=0;
    	while(!q.empty()){
    		int u=q.front();q.pop();vis[u]=0;
    		for(int i=first[u];i;i=e[i].nxt){
    			int v=e[i].v;
    			if(dis[v]>dis[u]+1){
    				dis[v]=dis[u]+1;
    				if(!vis[v]){
    					vis[v]=1;
    					q.push(v);
    				}
    			}
    		}
    	}
    	for(int i=1;i<=50;++i) q.push(i),ve[i].push_back(make_pair(0,0));
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		sort(ve[u].begin(),ve[u].end());
    		printf("node %d\n",u);
    		int v=0;
    		for(int i=first[u];i;i=e[i].nxt){
    			if(dis[u]==dis[e[i].v]+1){
    				v=e[i].v;
    				break;
    			}
    		}
    		for(int i=0;i<ve[u].size();++i){
    			printf("read %d a\n",ve[u][i].second);
    			printf("write a %d\n",v);
    			ve[last[u]].push_back(make_pair(ve[u][i].first+1,u));
    		}
    		if(v) q.push(v);
    	}
    }
    int b[N],U[N],V[N];
    int main(){
    	freopen("oldcomputer4.in","r",stdin);
    	freopen("oldcomputer4.out","w",stdout);
    	scanf("%d%d%d",&t,&n,&m);
    	for(int i=1,u,v;i<=m;++i)
    		scanf("%d%d",&u,&v),add(u,v),add(v,u);
    	SPFA();
    	return 0;
    }
    

    Subtask 5

    比较玄学,跑最短路的时候记一下\(used_{i.t}\)数组表示计算机\(i\)\(t\)时刻是否空闲,那么在用\(u\)松弛\(v\)时,如果\(w=dis[u]+1\)\(v\)不空闲,那么就不断增加\(w\),像这样跑\(10\)\(SPFA\)

    但是这个做法不一定是最优的,按顺序加边无法通过,改变一下加边顺序就可以·通过了:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    int t,n,m,first[N],ru[N],cnt,First[N],Cnt;
    struct node{
    	int v,nxt;
    }e[N<<1],E[N<<1];
    inline void add(int u,int v){
    	e[++cnt].v=v;e[cnt].nxt=first[u];first[u]=cnt;
    }
    int dis[N],vis[N],last[N],used[N][N],tim[N],ans=0;
    vector<pair<int,pair<int,int>> > ve[N];
    #define mp(a,b,c) make_pair(a,make_pair(b,c))
    inline void SPFA(int s,int t){
    	queue<int>q;
    	memset(dis,0x3f,sizeof(dis));
    	memset(vis,0,sizeof(vis));
    	q.push(s);dis[s]=0;vis[s]=1;
    	while(!q.empty()){
    		int u=q.front();q.pop();vis[u]=0;
    		for(int i=first[u];i;i=e[i].nxt){
    			int v=e[i].v;
    			int t=dis[u]+1;
    			while(used[v][t]||used[v][t+1]) ++t;
    			if(t<dis[v]){
    				dis[v]=t;last[v]=u;tim[v]=t;
    				if(!vis[v]){
    					vis[v]=1;
    					q.push(v);
    				}
    			}
    		}
    	}
    	int from=0;
    	while(1){
    		used[t][tim[t]]=used[t][tim[t]+1]=1;
    		ve[t].push_back(mp(tim[t],last[t],from));
    		ans=max(ans,tim[t]);
    		from=t;t=last[t];
    		if(t==s){
    			ve[t].push_back(mp(0,0,from));
    			break;
    		}
    	}
    }
    int b[N],U[N],V[N];
    int main(){
    	freopen("oldcomputer5.in","r",stdin);
    	freopen("oldcomputer5.out","w",stdout);
    	scanf("%d%d%d",&t,&n,&m);
    	for(int i=1,u,v;i<=m;++i)
    		scanf("%d%d",&U[i],&V[i]);
    	for(int i=m;i>=1;--i)
    		add(V[i],U[i]),add(U[i],V[i]);
    	for(int i=1;i<=10;++i) used[i][0]=used[i][1]=1,b[i]=i;
    	for(int i=1;i<=10;++i) SPFA(i,101-i);
    	for(int i=1;i<=n;++i){
    		if(ve[i].empty()) continue;
    		printf("node %d\n",i);
    		sort(ve[i].begin(),ve[i].end());
    		for(int j=0;j<ve[i].size();++j){
    			printf("read %d a\n",ve[i][j].second.first);
    			printf("write a %d\n",ve[i][j].second.second);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    四则运算---3
    四则运算---2
    四则运算---1
    我的软工实践总结
    用例图练习..................................................
    第四次作业——个人作业——软件案例分析
    第三次作业——将排课Excel导入系统
    第二次作业——结对项目之需求分析与原型模型设计
    软工实践练习一(个人)----将Androidstudio的项目共享到github
    第一次作业---安卓开发工具Android studio发展演变
  • 原文地址:https://www.cnblogs.com/tqxboomzero/p/14204801.html
Copyright © 2020-2023  润新知