NOJ-演算法設計實驗-test3

Phoenix_ZengHao發表於2020-10-25

原網站:http://phoenix-zh.cn/2020/10/23/NOJ-test3/

先佔個坑,等什麼時候有空了,再補題解,先貼上程式碼.

程式碼都不長,就是簡單bfs.vis標記注意狀態.除了特殊的二階魔方是真的噁心!

A.加1乘2平方

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int maxn=10000+50; 
int n,m,vis[maxn];
int min(int x,int y){
	return x<=y?x:y;
}
int main(){
	cin>>m>>n;
	memset(vis,0x3f3f3f3f,sizeof(vis));
	vis[m]=1;
	for(int i=m+1;i<=n;i++){
		int t=sqrt(i);
		if(vis[i-1])vis[i]=min(vis[i],vis[i-1]+1);
		if(i%2==0&&vis[i/2])vis[i]=min(vis[i],vis[i/2]+1);
		if(t*t==i&&vis[t])vis[i]=min(vis[i],vis[t]+1);
	}
	cout<<vis[n]-1<<endl;
	return 0;
}

B.電子老鼠闖迷宮

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=205;
int n,m,sx,sy,tx,ty,a[maxn][maxn],vis[maxn][maxn];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct Point{
	int x,y,cnt;
};
int min(int x,int y){
	return x<=y?x:y;
}
int main(){
	cin>>sx>>sy>>tx>>ty;m=n=12;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			char x;cin>>x;
			if(x=='.')a[i][j]=1;
		}
	queue<Point>q;
	Point now;
	now.x=sx;now.y=sy;now.cnt=0;
	vis[sx][sy]=1;
	q.push(now);
	int ans=0x3f3f3f3f;
	while(!q.empty()){
		now=q.front();q.pop();
		if(now.x==tx&&now.y==ty){
			ans=min(ans,now.cnt);
			continue;
		}
		if(now.cnt>ans)continue;
		for(int i=0;i<4;i++){
			if(now.x+dx[i]>=1&&now.x+dx[i]<=n&&now.y+dy[i]>=1&&now.y+dy[i]<=m&&!vis[now.x+dx[i]][now.y+dy[i]]&&a[now.x+dx[i]][now.y+dy[i]]){
				Point nex;nex.x=now.x+dx[i];nex.y=now.y+dy[i];nex.cnt=now.cnt+1;
				vis[nex.x][nex.y]=1;
				q.push(nex);
			}
		}
	}	
	cout<<ans<<endl;
	return 0;
}

C.跳馬

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=200+50;
int T,xs,xt,ys,yt,vis[maxn][maxn];
struct Node{
	int x,y,s;
};
int d[8][2]={{1,2},{2,1},{2,-1},{1,-2},{-2,1},{-1,2},{-2,-1},{-1,-2}};
int main(){
	cin>>T;
	while(T--){
		int i;
		memset(vis,0,sizeof(vis));
		cin>>xs>>ys>>xt>>yt;
		queue<Node>q;
		Node now={xs,ys,0};
		q.push(now);
		int step=0,ans=0;
		while(!q.empty()){
			now=q.front();q.pop();
			if(vis[now.x][now.y])continue;
			if(now.x==xt&&now.y==yt){
				ans=now.s;
				break;
			}
			vis[now.x][now.y]=1;
			for(i=0;i<8;i++){
				int x=now.x+d[i][0],y=now.y+d[i][1];
				if(x>=1&&x<=200&&y>=1&&y<=200){
					Node nex={x,y,now.s+1};
					q.push(nex);
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
} 

D.獨輪車

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=20+5;
const int maxm=5+5;
struct Node{
	int x,y,s,c,f;
};
int d[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
int vis[maxn][maxn][maxm][maxm];
int xs,xt,ys,yt,F;char f,col1,col2,a[maxn][maxn];
int main(){
	cin>>xs>>ys>>col1>>f;
	cin>>xt>>yt>>col2;
	int n=20;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		}
	}
	int c1,c2;
	if(col1=='R')c1=0;
	else if(col1=='Y')c1=1;
	else if(col1=='B')c1=2;
	else if(col1=='W')c1=3;
	else if(col1=='G')c1=4;
	if(col2=='R')c2=0;
	else if(col2=='Y')c2=1;
	else if(col2=='B')c2=2;
	else if(col2=='W')c2=3;
	else if(col2=='G')c2=4;
	if(f=='N')F=0;
	else if(f=='E')F=1;
	else if(f=='S')F=2;
	else if(f=='W')F=3;
	Node now={xs,ys,0,c1,F};
	queue<Node>q;q.push(now);
	int ans=0;
	while(!q.empty()){
		now=q.front();q.pop();
		if(!(now.x>=1&&now.x<=n&&now.y>=1&&now.y<=n)||a[now.x][now.y]=='X')continue;
		if(vis[now.x][now.y][now.c][now.f])continue;
		vis[now.x][now.y][now.c][now.f]=1;
		if(now.x==xt&&now.y==yt&&now.c==c2){
			ans=now.s;
			break;
		}
		Node nex;nex.x=now.x;nex.y=now.y;nex.s=now.s+1;nex.c=now.c;nex.f=(now.f+1)%4;
		q.push(nex);
	//	nex.x=now.x;nex.y=now.y;nex.s=now.s+1;nex.c=now.c;nex.f=(now.f+2)%4;
	//	q.push(nex);//注意是旋轉90° 
		nex.x=now.x;nex.y=now.y;nex.s=now.s+1;nex.c=now.c;nex.f=(now.f+3)%4;
		q.push(nex);
		if(now.f==0){
			nex.x=now.x-1;nex.y=now.y;nex.s=now.s+1;nex.c=(now.c+1)%5;nex.f=now.f;
			q.push(nex);
		}
		else if(now.f==1){
			nex.x=now.x;nex.y=now.y+1;nex.s=now.s+1;nex.c=(now.c+1)%5;nex.f=now.f;
			q.push(nex);
		}
		else if(now.f==2){
			nex.x=now.x+1;nex.y=now.y;nex.s=now.s+1;nex.c=(now.c+1)%5;nex.f=now.f;
			q.push(nex);
		}
		else if(now.f==3){
			nex.x=now.x;nex.y=now.y-1;nex.s=now.s+1;nex.c=(now.c+1)%5;nex.f=now.f;
			q.push(nex);
		}
	}
	cout<<ans<<endl;
	return 0;
}

E.六數碼問題

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=10+5;
struct Node{
	int a[10][10],s;
};
int a[10][10];
int main(){
	while(cin>>a[1][1]>>a[1][2]>>a[1][3]>>a[2][1]>>a[2][2]>>a[2][3]){
		Node now;
		for(int i=1;i<=2;i++){
			for(int j=1;j<=3;j++){
				now.a[i][j]=a[i][j];
			}
		}
		queue<Node>q;
		now.s=0;
		q.push(now);
		int ans=0x3f3f3f3f,cnt=0;
		while(!q.empty()){
			cnt++;
			now=q.front();q.pop();
			int sign=0;
			for(int i=1;i<=2;i++){
				for(int j=1;j<=3;j++){
					if(now.a[i][j]!=(i-1)*3+j){
						sign=1;
						break;
					}
				}
				if(sign)break;
			}
			if(!sign||cnt>=1000){
				if(sign==0)
				ans=now.s;
				break;
			}
			Node nex1=now,nex2=now;
			int t=nex1.a[2][1];nex1.a[2][1]=nex1.a[2][2];nex1.a[2][2]=nex1.a[1][2];nex1.a[1][2]=nex1.a[1][1];nex1.a[1][1]=t;
			t=nex2.a[2][2];nex2.a[2][2]=nex2.a[2][3];nex2.a[2][3]=nex2.a[1][3];nex2.a[1][3]=nex2.a[1][2];nex2.a[1][2]=t;
			nex1.s++;nex2.s++;
			q.push(nex1);
			q.push(nex2);
		}
		if(ans==0x3f3f3f3f){
			cout<<"No"<<endl;
		}
		else{
			cout<<"Yes"<<endl;
		}	
	}
}

F.特殊的二階魔方

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
struct Node{
	int a[7][4][4],st,s;
};
map<int,int>mp;
int main(){
	Node now;now.st=0;
	int i,j,k;
	for(i=1;i<=6;i++){
		for(j=1;j<=2;j++){
			for(k=1;k<=2;k++){
				char x;cin>>x;
				now.a[i][j][k]=x-'0';
				now.s=now.s*2+now.a[i][j][k];
			}
		}
	}
	queue<Node>q;
	q.push(now);
	int ans=0x3f3f3f3f;
	while(!q.empty()){
		now=q.front();q.pop();
		if(mp[now.s])continue;
		mp[now.s]=1;
		for(i=1;i<=6;i++){
			int sign=0;
			for(j=1;j<=2;j++){
				for(k=1;k<=2;k++){
					if(now.a[i][j][k]==1){
						sign=1;
					}
				}
			}
			if(!sign){
				cout<<now.st<<endl;
				return 0;
			}
		}
		Node nex=now;nex.st++;nex.s=0;
		//1-Up 2-Down 3-Lefe 4-Right 5-front 6-back
		//DR 
		nex.a[6][2][1]=now.a[3][2][2];nex.a[6][2][2]=now.a[3][2][1];
		nex.a[3][2][2]=now.a[5][2][2];nex.a[3][2][1]=now.a[5][2][1];
		nex.a[5][2][1]=now.a[4][2][2];nex.a[5][2][2]=now.a[4][2][1];
		nex.a[4][2][1]=now.a[6][2][1];nex.a[4][2][2]=now.a[6][2][2];
		nex.a[2][1][1]=now.a[2][2][1];nex.a[2][1][2]=now.a[2][1][1];nex.a[2][2][2]=now.a[2][1][2];nex.a[2][2][1]=now.a[2][2][2];
		for(i=1;i<=6;i++){
			for(j=1;j<=2;j++){
				for(k=1;k<=2;k++){
					nex.s=nex.s*2+nex.a[i][j][k];
				}
			}
		}
		q.push(nex);
		//DL
		nex=now;nex.st++;nex.s=0;
		nex.a[6][2][1]=now.a[4][2][1];nex.a[6][2][2]=now.a[4][2][2];
		nex.a[3][2][1]=now.a[6][2][2];nex.a[3][2][2]=now.a[6][2][1];
		nex.a[5][2][1]=now.a[3][2][1];nex.a[5][2][2]=now.a[3][2][2];
		nex.a[4][2][1]=now.a[5][2][2];nex.a[4][2][2]=now.a[5][2][1];
		nex.a[2][1][1]=now.a[2][1][2];nex.a[2][1][2]=now.a[2][2][2];nex.a[2][2][2]=now.a[2][2][1];nex.a[2][2][1]=now.a[2][1][1];
		for(i=1;i<=6;i++){
			for(j=1;j<=2;j++){
				for(k=1;k<=2;k++){
					nex.s=nex.s*2+nex.a[i][j][k];
				}
			}
		}
		q.push(nex);
		//RU
		nex=now;nex.st++;nex.s=0;
		nex.a[1][1][2]=now.a[5][1][2];nex.a[1][2][2]=now.a[5][2][2];
		nex.a[5][1][2]=now.a[2][2][2];nex.a[5][2][2]=now.a[2][1][2];
		nex.a[2][1][2]=now.a[6][1][2];nex.a[2][2][2]=now.a[6][2][2];
		nex.a[6][1][2]=now.a[1][2][2];nex.a[6][2][2]=now.a[1][1][2]; 
		nex.a[4][1][1]=now.a[4][1][2];nex.a[4][1][2]=now.a[4][2][2];nex.a[4][2][2]=now.a[4][2][1];nex.a[4][2][1]=now.a[4][1][1];
		for(i=1;i<=6;i++){
			for(j=1;j<=2;j++){
				for(k=1;k<=2;k++){
					nex.s=nex.s*2+nex.a[i][j][k];
				}
			}
		}
		q.push(nex);
		//RD
		nex=now;nex.st++;nex.s=0;
		nex.a[1][1][2]=now.a[6][2][2];nex.a[1][2][2]=now.a[6][1][2];
		nex.a[6][1][2]=now.a[2][1][2];nex.a[6][2][2]=now.a[2][2][2];
		nex.a[2][1][2]=now.a[5][2][2];nex.a[2][2][2]=now.a[5][1][2];
		nex.a[5][1][2]=now.a[1][1][2];nex.a[5][2][2]=now.a[1][2][2]; 
		nex.a[4][1][1]=now.a[4][2][1];nex.a[4][2][1]=now.a[4][2][2];nex.a[4][2][2]=now.a[4][1][2];nex.a[4][1][2]=now.a[4][1][1];
		for(i=1;i<=6;i++){
			for(j=1;j<=2;j++){
				for(k=1;k<=2;k++){
					nex.s=nex.s*2+nex.a[i][j][k];
				}
			}
		}
		q.push(nex);
		//C
		nex=now;nex.st++;nex.s=0;
		nex.a[1][1][1]=now.a[3][2][1];nex.a[1][1][2]=now.a[3][1][1];
		nex.a[3][1][1]=now.a[2][1][1];nex.a[3][2][1]=now.a[2][1][2];
		nex.a[2][1][1]=now.a[4][2][1];nex.a[2][1][2]=now.a[4][1][1];
		nex.a[4][1][1]=now.a[1][1][1];nex.a[4][2][1]=now.a[1][1][2];
		nex.a[6][1][1]=now.a[6][2][1];nex.a[6][2][1]=now.a[6][2][2];nex.a[6][2][2]=now.a[6][1][2];nex.a[6][1][2]=now.a[6][1][1];
		for(i=1;i<=6;i++){
			for(j=1;j<=2;j++){
				for(k=1;k<=2;k++){
					nex.s=nex.s*2+nex.a[i][j][k];
				}
			}
		}
		q.push(nex);
		//CC
		nex=now;nex.st++;nex.s=0;
		nex.a[1][1][1]=now.a[4][1][1];nex.a[1][1][2]=now.a[4][2][1];
		nex.a[4][1][1]=now.a[2][1][2];nex.a[4][2][1]=now.a[2][1][1];
		nex.a[2][1][1]=now.a[3][1][1];nex.a[2][1][2]=now.a[3][2][1];
		nex.a[3][1][1]=now.a[1][1][2];nex.a[3][2][1]=now.a[1][1][1];
		nex.a[6][1][1]=now.a[6][1][2];nex.a[6][1][2]=now.a[6][2][2];nex.a[6][2][2]=now.a[6][2][1];nex.a[6][2][1]=now.a[6][1][1];
		for(i=1;i<=6;i++){
			for(j=1;j<=2;j++){
				for(k=1;k<=2;k++){
					nex.s=nex.s*2+nex.a[i][j][k];
				}
			}
		}
		q.push(nex);
	}
	cout<<"-1"<<endl;
	return 0;
}

G.推箱子

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=10+5;
struct Node{
	int xr,yr,x,y,s;
};
char a[maxn][maxn];int xt,yt;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}},vis[maxn][maxn][maxn][maxn];
int main(){
	int i;
	for(i=1;i<=10;i++)cin>>a[i]+1;
	queue<Node>q;
	Node now; 
	for(i=1;i<=10;i++){
		for(int j=1;j<=10;j++){
			if(a[i][j]=='2'){
				now.x=i;now.y=j;	
			}
			else if(a[i][j]=='3'){
				xt=i;yt=j;
			}
			else if(a[i][j]=='4'){
				now.xr=i;now.yr=j;
			}
		}
	}
	now.s=0;
	q.push(now);
	int ans=0x3f3f3f3f;
	while(!q.empty()){
		now=q.front();q.pop();
		if(vis[now.xr][now.yr][now.x][now.y])continue;
		vis[now.xr][now.yr][now.x][now.y]=1;
		if(now.xr<1||now.xr>10||now.yr<1||now.yr>10||now.x<1||now.x>10||now.y<1||now.y>10)continue;
		if(a[now.xr][now.yr]=='1'||a[now.x][now.y]=='1')continue;
		if(now.x==xt&&now.y==yt){
			ans=now.s;
			break;
		}
		for(i=0;i<4;i++){
			Node nex=now;
			nex.xr+=d[i][0],nex.yr+=d[i][1],nex.s++;
			if(nex.xr==nex.x&&nex.yr==nex.y){
				nex.x+=d[i][0];nex.y+=d[i][1];
				q.push(nex);
			}
			else{
				q.push(nex);
			}
		}
	}
	if(ans==0x3f3f3f3f)cout<<"-1"<<endl;
	else cout<<ans<<endl;
}

H.polygon

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=2000+50;
int n,m,vis[maxn];double len=10000.0,a[maxn],b[maxn];
int main(){
	cin>>n>>m;
	int i,j;
	for(i=1;i<=n;i++){
		a[i]=(i-1)*(len/n);
	}
	for(i=1;i<=n+m;i++){
		b[i]=(i-1)*(len/(n+m));
	}
	double ans=0;
	for(i=1;i<=n;i++){
		int opt=0;double maxx=1e9;
		for(j=1;j<=n+m;j++){
			if(!vis[j]&&fabs(a[i]-b[j])<maxx){
				maxx=fabs(a[i]-b[j]);
				opt=j;
			}
		}	
		vis[opt]=1;
		ans+=fabs(a[i]-b[opt]);
	}
	printf("%.4lf\n",ans);
	return 0;
}

I.木乃伊迷宮

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=10+5;
struct Node{
	int xr,yr,xm,ym;
};
int a[maxn][maxn][maxn],n,xt,yt,vis[maxn][maxn][maxn][maxn];
int d[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int main(){
	cin>>n;
	int i,j;
	for(i=1;i<=n;i++){
		int s,x,y;
		cin>>x>>y>>s;
		if(s==0){
			a[x][y][0]=a[x+1][y][3]=1;//下側 上側 
		}
		else{
			a[x][y][1]=a[x][y][2]=1;//右側 左側 ps: 我也不知道為什麼這裡錯的可以AC,原本對的WA。 
		}
	}
	Node now;
	cin>>now.xm>>now.ym>>now.xr>>now.yr>>xt>>yt;
	queue<Node>q;
	q.push(now);
	while(!q.empty()){
		now=q.front();q.pop();
		if(vis[now.xr][now.yr][now.xm][now.ym])continue;
		vis[now.xr][now.yr][now.xm][now.ym]=1;
		Node nex;
		if(now.xr==xt&&now.yr==yt){
			cout<<"Yes"<<endl;
			return 0;
		}
		for(int i=0;i<4;i++){
			Node nex;
			if(i==0&&a[now.xr][now.yr][0])continue;
			if(i==1&&a[now.xr][now.yr][3])continue;
			if(i==2&&a[now.xr][now.yr][1])continue;
			if(i==3&&a[now.xr][now.yr][2])continue;
			nex.xr=now.xr+d[i][0];nex.yr=now.yr+d[i][1];
			if(nex.xr<0||nex.xr>=6||nex.yr<0||nex.yr>=6)continue;
			int res=2;
			while(now.yr!=now.ym&&res){
				if(now.ym>now.yr&&!a[now.xm][now.ym][2])now.ym--;
				else if(now.ym<now.yr&&!a[now.xm][now.ym][1])now.ym++;
				res--;
			}
			while(res){
				if(now.xm>now.xr&&!a[now.xm][now.ym][3])now.xm--;
				else if(now.xm<now.xr&&!a[now.xm][now.ym][0])now.xm++;
				if(now.xm==now.xr&&now.ym==now.yr)break;
				res--;
			}
			if(!res){
				nex.xm=now.xm;nex.ym=now.ym;
				q.push(nex);
			}
		}
	}
	cout<<"No"<<endl;
	return 0;
}

J.八數碼

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
const int maxn=20+5;
struct Node{
	int s,a[5][5],state;
}; 
int a[maxn][maxn],t[maxn][maxn],state;map<int,int>mp;
int main(){
	int i,j;Node now;now.state=0;now.s=0;
	for(i=1;i<=3;i++){
		for(j=1;j<=3;j++){
			cin>>now.a[i][j];
			now.state=now.state*10+now.a[i][j];
			t[i][j]=(i-1)*3+j;
			state=state*10+t[i][j];
		}
	}
	state-=9;
	t[3][3]=0;
	queue<Node>q;
	int ans=0x3f3f3f3f;
	q.push(now);
	while(!q.empty()){
		now=q.front();q.pop();
		if(mp[now.state])continue;
		mp[now.state]=1;
		for(i=1;i<=3;i++){
			int sign=0;
			for(j=1;j<=3;j++){
				if(now.a[i][j]==0){
					sign=1;break;
				}
			}
			if(sign)break;
		}
		if(now.state==state){
			ans=now.s;
			break;
		}
		Node nex=now;
		if(j>=2){
			swap(nex.a[i][j],nex.a[i][j-1]);
			nex.state=0;
			for(int i=1;i<=3;i++){
				for(int j=1;j<=3;j++){
					nex.state=nex.state*10+nex.a[i][j];
				}
			}
			nex.s++;
			q.push(nex);
		}
		nex=now;
		if(j<=2){
			swap(nex.a[i][j],nex.a[i][j+1]);
			nex.state=0;
			for(int i=1;i<=3;i++){
				for(int j=1;j<=3;j++){
					nex.state=nex.state*10+nex.a[i][j];
				}
			}
			nex.s++;
			q.push(nex);
		}
		nex=now;
		if(i>=2){
			swap(nex.a[i][j],nex.a[i-1][j]);
			nex.state=0;
			for(int i=1;i<=3;i++){
				for(int j=1;j<=3;j++){
					nex.state=nex.state*10+nex.a[i][j];
				}
			}
			nex.s++;
			q.push(nex);
		}
		nex=now;
		if(i<=2){
			swap(nex.a[i][j],nex.a[i+1][j]);
			nex.state=0;
			for(int i=1;i<=3;i++){
				for(int j=1;j<=3;j++){
					nex.state=nex.state*10+nex.a[i][j];
				}
			}
			nex.s++;
			q.push(nex);
		}
	}
	if(ans==0x3f3f3f3f)cout<<"-1"<<endl;
	else cout<<ans<<endl;
	return 0;
}


相關文章