A:
八皇后类似,但略有区别:不一定要放满n个棋子
(我随便码的……这都能一次过?!)
就按八皇后思路,每一层两种选择,不放棋子/在1-n列中合法的地方放棋子
然后cnt>n即return这个地方第一次没有写到,调试发现会死循环才补上的
#include<stdio.h>
int n,k,ans;
char map1[10][10];
int map[10][10];
int vis[10];//标记0-n列有无棋子
void dfs(int cnt,int num){//层数,已经放了num个棋子
if(num==k){
ans++;
return;
}
if(cnt>n) return;
dfs(cnt+1,num);
for(int j=0;j<n;j++){
if(vis[j]==0&&map[cnt][j]==0){
vis[j]=1;
dfs(cnt+1,num+1);
vis[j]=0;
}
}
}
int main()
{
while(scanf("%d%d",&n,&k)==2&&n!=-1&&k!=-1){
for(int i=1;i<=n;i++) scanf("%s",map1[i]);
for(int i=1;i<=n;i++){
for(int j=0;j<n;j++){
if(map1[i][j]=='#') map[i][j]=0;
else map[i][j]=1;
}
}
ans=0;
dfs(1,0);
printf("%d\n",ans);
}
return 0;
}
B:
队列里放结构体的做法还不是很熟练,不过这回写下来就会了
然后总体很顺畅,但写出了两个bug
一是标记是否访问的问题,一开始没有写 !vis[sz][sx][sy] 这一条件,直接TLE
二是队列q的声明,一开始放在了最外面,但它应该放在每个样例,即while循环的里面,否则一直用的都是同一个队列,上一个样例遗留下来的队内元素影响到了下一个样例……也是一直WA的原因
#include<stdio.h>
#include<queue>
#include<string.h>
#include<iostream>
using namespace std;
char cube[35][35][35];
int vis[35][35][35];
struct node{
int z,x,y;
int step;
};
int dz[]={-1,1,0,0,0,0};
int dx[]={0,0,1,-1,0,0};
int dy[]={0,0,0,0,1,-1};
int main(){
int l,r,c,sx,sy,sz;
node t;
while(scanf("%d%d%d",&l,&r,&c)==3&&l&&r&&c){
queue<node>q;
memset(vis,0,sizeof(vis));
for(int i=1;i<=l;i++){
for(int j=1;j<=r;j++){
for(int k=1;k<=c;k++){
cin>>cube[i][j][k];
//printf("%c",cube[i][j][k]);
if(cube[i][j][k]=='S'){
t.z=i;
t.x=j;
t.y=k;
t.step=0;
q.push(t);
}
}
//printf("\n");
}
}
int ok=0;
while(!q.empty()){
node now=q.front();
q.pop();
int nz=now.z;
int nx=now.x;
int ny=now.y;
if(cube[nz][nx][ny]=='E'){
cout<<"Escaped in "<<now.step<<" minute(s)."<<endl;
ok=1;
break;
}
for(int i=0;i<6;i++){
node next;
sx=next.x=nx+dx[i];
sy=next.y=ny+dy[i];
sz=next.z=nz+dz[i];
next.step=now.step+1;
if(sx<1||sy<1||sz<1||sx>r||sy>c||sz>l) continue;
if(cube[sz][sx][sy]!='#'&&!vis[sz][sx][sy]){
vis[sz][sx][sy]=1;
q.push(next);
}
}
}
if(ok==0) cout<<"Trapped!"<<endl;
}
return 0;
}
C:
农民要去抓牛。在一条笔直的路上,牛的位置为k,不动。农民从位置n出发,每次可以移动到位置n-1或n+1或2n,每次移动都花费1分钟,问抓到牛的最短时间
本来想用dp做,可是dp[i]=dp[i-1]+dp[i+1]+dp[2i]……由于dp[i+1]的存在,是倒推不了的
然后bfs一遍过
#include<stdio.h>
#include<queue>
using namespace std;
int vis[100005];
int main()
{
queue<int>q;
int n,k;
scanf("%d%d",&n,&k);
q.push(n);
while(!q.empty()){
int x=q.front();
q.pop();
if(x==k){
printf("%d",vis[x]);
break;
}
int nx;
nx=x-1;
if(nx>=0&&nx<=100000&&vis[nx]==0){
vis[nx]=vis[x]+1;
q.push(nx);
}
nx=x+1;
if(nx>=0&&nx<=100000&&vis[nx]==0){
vis[nx]=vis[x]+1;
q.push(nx);
}
nx=x*2;
if(nx>=0&&nx<=100000&&vis[nx]==0){
vis[nx]=vis[x]+1;
q.push(nx);
}
}
return 0;
}
K:
普通的走迷宫问题。BFS都快写完了才发现它要求输出路径,考虑到只是个5*5迷宫且路径唯一,DFS可行。
首先这题和P1101 单词方阵这题很像,关键点在于要把记录路径的结构体数组也作为参数传入DFS函数中,从而达到“只保存最短路径”的目的。
然后也出了一点小差错,比如说因为它是5*5迷宫,不知怎么的就觉得走5步就可以了……可能是因为参考了上面这道单词方阵,思路乱了。
一遍过啦。
#include<stdio.h>
#include<iostream>
using namespace std;
int vis[7][7];
int map[7][7];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
struct node{
int x,y;
};
void dfs(int ans,node c[],int x,int y){
if(x==5&&y==5){
for(int i=1;i<=ans-1;i++){
printf("(%d, %d)\n",c[i].x-1,c[i].y-1);
}
}
for(int i=0;i<4;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=1&&ny>=1&&nx<=5&&ny<=5){
if(map[nx][ny]!=1&&!vis[nx][ny]){
vis[nx][ny]=1;
c[ans].x=nx;
c[ans].y=ny;
dfs(ans+1,c,nx,ny);
}
}
}
}
int main()
{
for(int i=1;i<=5;i++){
for(int j=1;j<=5;j++){
cin>>map[i][j];
}
}
node c[30];
vis[1][1]=1;
c[1].x=1;
c[1].y=1;
dfs(2,c,1,1);
return 0;
}
L:
做烂了,略