题目1456:胜利大逃亡
时间限制:1 秒
内存限制:128 兆
特殊判题:否
提交:3091
解决:1111
题目描述:
Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会.魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从一个坐标走到相邻的六个坐标中的其中一个.现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1.
输入:
输入数据的第一行是一个正整数K,表明测试数据的数量.每组测试数据的第一行是四个正整数A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它们分别代表城堡的大小和魔王回来的时间.然后是A块输入数据(先是第0块,然后是第1块,第2块......),每块输入数据有B行,每行有C个正整数,代表迷宫的布局,其中0代表路,1代表墙。
输出:
对于每组测试数据,如果Ignatius能够在魔王回来前离开城堡,那么请输出他最少需要多少分钟,否则输出-1.
样例输入:
1 3 3 4 20 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 1 1 0 0 1 1 0
样例输出:
11
代码:
#include <stdio.h>
#include <queue>
using namespace std;
bool mark[50][50][50];
int maze [50][50][50];
struct N{
int x,y,z;
int t;
};
queue<N> Q;
int go[][3]={
1,0,0,
-1,0,0,
0,1,0,
0,-1,0,
0,0,1,
0,0,-1
};
int BFS(int a,int b,int c){
while(Q.empty()==false){
N now=Q.front();
Q.pop();
int i;
for(i=0;i<6;i++){
int nx=now.x+go[i][0];
int ny=now.y+go[i][1];
int nz=now.z+go[i][2];
if(nx<0||nx>=a||ny<0||ny>=b||nz<0||nz>=c) continue;
if(maze[nx][ny][nz]==1) continue;
if(mark[nx][ny][nz]==true) continue;
N tmp;
tmp.x=nx;
tmp.y=ny;
tmp.z=nz;
tmp.t=now.t+1;
Q.push(tmp);
mark[nx][ny][nz]=true;
if(nx==a-1&&ny==b-1&&nz==c-1) return tmp.t;
}
}
return -1;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int a,b,c,t;
scanf("%d%d%d%d",&a,&b,&c,&t);
int i;
for(i=0;i<a;i++){
int j;
for(j=0;j<b;j++){
int k;
for(k=0;k<c;k++){
scanf("%d",&maze[i][j][k]);
mark[i][j][k]=false;
}
}
}
while(Q.empty()==false) Q.pop();
mark[0][0][0]=true;
N tmp;
tmp.t=tmp.x=tmp.y=tmp.z=0;
Q.push(tmp);
int rec=BFS(a,b,c);
if(rec<=t) printf("%d\n",rec);
else printf("-1\n");
}
return 0;
}
题目1457:非常可乐
时间限制:1 秒
内存限制:128 兆
特殊判题:否
提交:1262
解决:595
题目描述:
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升(正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
输入:
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
输出:
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
样例输入:
7 4 3 4 1 3 0 0 0
样例输出:
NO 3
代码:
#include <stdio.h>
#include <queue>
using namespace std;
struct N{
int a,b,c;
int t;
};
queue<N> Q;
bool mark[101][101][101];
void AtoB(int &a,int sa,int &b,int sb){
if(sb-b>=a){
b+=a;
a=0;
}else{
a-=sb-b;
b=sb;
}
}
int BFS(int s,int n,int m){
while(Q.empty()==false){
N now=Q.front();
Q.pop();
int a,b,c;
a=now.a;
b=now.b;
c=now.c;
AtoB(a,s,b,n);
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2) return tmp.t;
if(a==s/2&&c==s/2) return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;
AtoB(b,n,a,s);
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2) return tmp.t;
if(a==s/2&&c==s/2) return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;
AtoB(a,s,c,m);
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2) return tmp.t;
if(a==s/2&&c==s/2) return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;
AtoB(c,m,a,s);
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2) return tmp.t;
if(a==s/2&&c==s/2) return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;
AtoB(b,n,c,m);
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2) return tmp.t;
if(a==s/2&&c==s/2) return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;
AtoB(c,m,b,n);
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2) return tmp.t;
if(a==s/2&&c==s/2) return tmp.t;
Q.push(tmp);
}
}
return -1;
}
int main(){
int s,n,m;
while(scanf("%d%d%d",&s,&n,&m)!=EOF){
if(s==0) break;
if(s%2==1){
puts("NO");
continue;
}
int i;
for(i=0;i<=s;i++){
int j;
for(j=0;j<=n;j++){
int k;
for(k=0;k<=m;k++){
mark[i][j][k]=false;
}
}
}
N tmp;
tmp.a=s;
tmp.b=0;
tmp.c=0;
tmp.t=0;
while(Q.empty()==false) Q.pop();
Q.push(tmp);
mark[s][0][0]=true;
int rec=BFS(s,n,m);
if(rec==-1)
puts("NO");
else
printf("%d\n",rec);
}
return 0;
}