Loading

P5207 [WC2019] 远古计算机 - 提交答案,图论

任务 \(1\)

周期 \(\le 200\)

直接模拟即可。

node 1
read 0 a
write a 0
jmp 1

任务 \(2\)

周期 \(\le 4\)

因为保证了 \(F_k\le 10^9\),所以 \(k\le 44\),所以直接把 \(\le 44\) 的斐波那契数算出来,然后 jmp 到正确的位置即可。

#define For(Ti,Ta,Tb) for(int Ti=(Ta);Ti<=(Tb);++Ti)
#define Dec(Ti,Ta,Tb) for(int Ti=(Ta);Ti>=(Tb);--Ti)
const int N=44;
int f[N+1];
int main(){
	freopen("oldcomputer2.out","w",stdout);
	cout<<"node 1\n";
	cout<<"read 0 a\n";
	cout<<"add a 4\n";
	cout<<"jmp a\n";
	f[0]=0,f[1]=1;
	For(i,2,N) f[i]=f[i-1]+f[i-2];
	For(i,0,N){
		cout<<"write "<<f[i]<<" 0\n";
	}
	return 0;
}

任务 \(3\)

周期 \(\le 211\)

我们求出 \(1\to 100\) 的最短路,按照这个最短路传输即可。

#define For(Ti,Ta,Tb) for(int Ti=(Ta);Ti<=(Tb);++Ti)
#define Dec(Ti,Ta,Tb) for(int Ti=(Ta);Ti>=(Tb);--Ti)
int a[]={100,80,98,56,37,36,50,40,54,13,7,1};
int main(){
	freopen("oldcomputer3.out","w",stdout);
	reverse(begin(a),end(a));
	for(auto it=begin(a);it!=end(a);++it){
		cout<<"node "<<*it<<"\n";
		cout<<"read "<<(it==begin(a)?0:*prev(it))<<" a\n";
		cout<<"write a "<<(it==prev(end(a))?0:*next(it))<<"\n";
	}
	return 0;
}

任务 \(4\)

周期 \(\le 7\)

可以发现最短路不一定最优,因为执行的过程是多线程的,不能让一个点有过多的操作。我的方法比较笨,就是先求出来最短路再手动微调……

#define For(Ti,Ta,Tb) for(int Ti=(Ta);Ti<=(Tb);++Ti)
#define Dec(Ti,Ta,Tb) for(int Ti=(Ta);Ti>=(Tb);--Ti)
const int N=1e5+5;
int _,n,m;
vector<int> g[N];
int dis[N],pre[N];
string prog[N];
int plen[N];
int Splen(int u){
	if(!u) return N;
	int res=0;
	while(u){
		res=max(res,plen[u]);
		u=pre[u];
	}
	return res;
}
int main(){
	freopen("oldcomputer4.in","r",stdin);
	freopen("oldcomputer4.out","w",stdout);
	cin>>_>>n>>m;
	For(i,1,m){
		int u,v;cin>>u>>v;
		g[u].push_back(v),g[v].push_back(u);
	}
	For(S,1,50){
		memset(dis,0x3f,sizeof dis);
		memset(pre,0,sizeof pre);
		queue<int> q;
		q.push(S),dis[S]=0;
		while(!q.empty()){
			int u=q.front();q.pop();
			for(int v:g[u]){
				if(dis[v]>dis[u]+1){
					dis[v]=dis[u]+1;
					pre[v]=u;
					q.push(v);
				}
			}
		}
		int T=0,mdis=dis[51];
		For(u,51,100) mdis=min(mdis,dis[u]);
		For(u,51,100){
			if(S==34&&dis[u]<=3){if(u!=68) T=u;}
			else if(dis[u]==mdis&&Splen(u)<Splen(T)&&(S!=17||u!=93)&&(S!=19||u!=58)&&(S!=43||(u!=58&&u!=59))&&(S!=27||u!=59)) T=u;
		}
		cerr<<S<<":"<<dis[T]<<endl;
		vector<int> pth;
		while(T){
			cerr<<T<<" ";
			pth.push_back(T);
			T=pre[T];
		}
		cerr<<endl;
		reverse(pth.begin(),pth.end());
		for(auto it=pth.begin();it!=pth.end();++it){
			if(it==pth.begin()) prog[*it]+="read 0 a\n";
			else prog[*it]+=string("read ")+to_string(*prev(it))+" a\n";
			if(it==prev(pth.end())) prog[*it]+="write a 0\n";
			else prog[*it]+=string("write a ")+to_string(*next(it))+"\n";
			plen[*it]+=2;
		}
	}
	For(i,1,n){
		cout<<"node "<<i<<"\n";
		cout<<prog[i];
	}
	return 0;
}

任务 \(5\)

周期 \(\le 21\)

这下微调不出来了,哈哈。去学习了一下正确的写法:记录每个点在每个时间是否被占用,最短路转移的时候找到最小的未被占用的时间。

#define For(Ti,Ta,Tb) for(int Ti=(Ta);Ti<=(Tb);++Ti)
#define Dec(Ti,Ta,Tb) for(int Ti=(Ta);Ti>=(Tb);--Ti)
const int N=1005;
int _,n,m;
vector<int> g[N];
int dis[N],pre[N],used[N][N],ven[N];
vector<pair<int,string>> prog[N];
int main(){
	freopen("oldcomputer5.in","r",stdin);
	freopen("oldcomputer5.out","w",stdout);
	cin>>_>>n>>m;
	For(i,1,m){
		int u,v;cin>>u>>v;
		g[u].push_back(v),g[v].push_back(u);
	}
	For(i,1,10) used[i][0]=used[i][1]=1;
	For(S,1,10){
		memset(dis,0x3f,sizeof dis);
		memset(pre,0,sizeof pre);
		memset(ven,0,sizeof ven);
		queue<int> q;
		q.push(S),dis[S]=0,ven[S]=1;
		while(!q.empty()){
			int u=q.front();q.pop();
			ven[u]=0;
			for(int v:g[u]){
				int w=dis[u]+1;
				while(used[v][w]||used[v][w+1]) ++w;
				if(w<dis[v]){
					dis[v]=w,pre[v]=u;
					if(!ven[v]) q.push(v),ven[v]=1;
				}
			}
		}
		int T=101-S;vector<int> pth;
		int u=T;
		while(u){
			pth.push_back(u);
			used[u][dis[u]]=used[u][dis[u]+1]=1;
			u=pre[u];
		}
		reverse(pth.begin(),pth.end());
		for(auto it=pth.begin();it!=pth.end();++it){
			if(it==pth.begin()) prog[*it].push_back({dis[*it],"read 0 a\n"});
			else prog[*it].push_back({dis[*it],string("read ")+to_string(*prev(it))+" a\n"});
			if(it==prev(pth.end())) prog[*it].push_back({dis[*it],"write a 0\n"});
			else prog[*it].push_back({dis[*it],string("write a ")+to_string(*next(it))+"\n"});
		}
	}
	For(i,1,n){
		cout<<"node "<<i<<"\n";
		stable_sort(prog[i].begin(),prog[i].end());
		for(const auto &x:prog[i]) cout<<x.second;
	}
	return 0;
}
posted @ 2022-01-26 20:48  Alan_Zhao_2007  阅读(39)  评论(0编辑  收藏  举报