![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<memory.h> 5 #include<string> 6 #define INF 0x3f3f3f3f 7 using namespace std; 8 9 const int indexs[8][7]= 10 { 11 {0,2,6,11,15,20,22}, 12 {1,3,8,12,17,21,23}, 13 {10,9,8,7,6,5,4}, 14 {19,18,17,16,15,14,13}, 15 {23,21,17,12,8,3,1}, 16 {22,20,15,11,6,2,0}, 17 {13,14,15,16,17,18,19}, 18 {4,5,6,7,8,9,10}, 19 }; 20 const int ni[]={5,4,7,6,1,0,3,2,-1}; 21 const int center[]={6,7,8,11,12,15,16,17}; 22 int min(int a,int b) {return a>b ? b : a;} 23 int max(int a,int b) {return a<b ? b : a;} 24 char map[24]; 25 char route[101]; 26 bool hasSolution; 27 28 void pull(int op) 29 { 30 int temp=map[indexs[op][0]]; 31 for (int i=0;i<7-1;i++) 32 { 33 map[indexs[op][i]]=map[indexs[op][i+1]]; 34 } 35 map[indexs[op][6]]=temp; 36 } 37 38 int h() 39 { 40 int cnt[3]={0,0,0}; 41 int maxCnt= -1; 42 for(int i=0;i<8;i++) 43 { 44 cnt[map[center[i]]-1]++; 45 maxCnt=max(maxCnt,cnt[map[center[i]]-1]);//作用和if.m>cnt.m=cnt[]一样; 46 } 47 return 8-maxCnt; 48 } 49 50 void dfs(int depth,int lastop,int maxdepth ) 51 { 52 if(hasSolution) return ; 53 if(h()==0) 54 { 55 hasSolution=true; 56 route[depth]='\0'; 57 printf("%s\n%d\n",route, map[center[0]]); 58 return; 59 } 60 if(depth>maxdepth||depth+h()>maxdepth) return; 61 for(int nextop=0;nextop<8;nextop++) 62 { 63 if(nextop != ni[lastop]) 64 { 65 pull(nextop); 66 route[depth]=nextop+'A'; 67 dfs(depth+1,nextop,maxdepth); 68 pull(ni[nextop]); 69 } 70 } 71 } 72 73 int main() 74 { 75 int x; 76 while(cin>>x&&x) 77 { 78 map[0]=x; 79 for(int i=1;i<24;i++) 80 { 81 cin>>map[i]; 82 if(map[i]==0) return 0; 83 } 84 hasSolution = false; 85 if(h()==0) 86 { 87 printf("No moves needed\n%d\n", map[center[0]]); 88 continue; 89 } 90 for(int depth =1;!hasSolution;depth++) 91 { 92 dfs(0,8,depth); 93 } 94 } 95 return 0; 96 }
第一题“井”
https://lo-li.net/1363.html
AC的代码。。求哪里不同啊。。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <string> 5 #include <memory.h> 6 using namespace std; 7 #define INF 0x3f3f3f3f 8 const int indexs[8][7] = { // 每种操作变动的下标 9 { 0,2,6,11,15,20,22 }, //AF 10 { 1,3,8,12,17,21,23 }, //BE 11 { 10,9,8,7,6,5,4 }, //CH 12 { 19,18,17,16,15,14,13 }, //DG 13 { 23,21,17,12,8,3,1 }, //EB 14 { 22,20,15,11,6,2,0 }, //FA 15 { 13,14,15,16,17,18,19 }, //GD 16 { 4,5,6,7,8,9,10 }, //HC 17 }; 18 const int reverseOp[] = { 5,4,7,6,1,0,3,2,-1 }; // A-H的逆操作 19 const int center[] = { 6,7,8,11,12,15,16,17 }; // 中心八点下标 20 int min(int a, int b) { return a>b ? b : a; } 21 int max(int a, int b) { return a<b ? b : a; } 22 char map[24]; 23 char route[101]; // 操作序列 24 bool hasSolution; 25 26 void pull(int op) { 27 int tmp = map[indexs[op][0]]; 28 for (int i = 0; i < 7 - 1; i++) { 29 map[indexs[op][i]] = map[indexs[op][i + 1]]; 30 } 31 map[indexs[op][6]] = tmp; 32 } 33 34 int h() { 35 int cnt[3] = { 0,0,0 }; // 计数 1, 2, 3 36 int maxCnt = -1; 37 for (int i = 0; i < 8; i++) { 38 cnt[map[center[i]] - 1]++; 39 maxCnt = max(maxCnt, cnt[map[center[i]] - 1]); 40 } 41 return 8 - maxCnt; 42 } 43 44 void d(int depth, int lastOp, int maxDepth) {// 当前深度、到达当前深度所做的操作 45 if (hasSolution)return; 46 if (h() == 0) { // 中心都相同了 47 hasSolution = true; 48 route[depth] = '\0'; 49 printf("%s\n%d\n",route, map[center[0]]); 50 return; 51 } 52 if (depth > maxDepth || depth + h() > maxDepth) return; // 可行性剪枝 53 for (int nextOp = 0; nextOp < 8; nextOp++) { 54 if (nextOp != reverseOp[lastOp]) { //操作不互逆 55 pull(nextOp); 56 route[depth] = nextOp + 'A'; 57 d(depth + 1, nextOp, maxDepth); 58 pull(reverseOp[nextOp]); //还原 59 } 60 } 61 } 62 int main() { 63 while (1) { 64 for (int i = 0; i < 24; i++) { 65 scanf("%d", &map[i]); 66 if (map[i] == 0) return 0; 67 } 68 hasSolution = false; 69 if (h() == 0) { 70 printf("No moves needed\n%d\n", map[center[0]]); 71 continue; 72 } 73 for (int depth = 1; !hasSolution; depth++) { // 迭代加深 74 d(0, 8, depth); 75 } 76 } 77 return 0; 78 }
第二题
Output
对于每个测试用例,打印一行,表示可以从这些序列中生成的最短序列的长度。
Sample Input
1
4
ACGT
ATGC
CGTT
CAGT
Sample Output
8
第二题的代码
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 char str[10][10];//记录n个字符串 7 int n,ans,deep,size[10]; 8 char DNA[4]={'A','C','G','T'};//一共四种可能 9 10 void dfs(int cnt,int len[]) 11 { 12 if(cnt > deep)//大于限制的深度,不用往下搜索 13 return; 14 int maxx = 0;//预计还要匹配的字符串的最大长度 15 for(int i=0;i<n;i++) 16 { 17 int t = size[i]-len[i]; 18 if(t>maxx) 19 maxx = t; 20 } 21 if(maxx==0)//条件全部满足即为最优解 22 { 23 ans = cnt; 24 return; 25 } 26 if(cnt + maxx > deep) 27 return; 28 for(int i=0;i<4;i++) 29 { 30 int pos[10]; 31 int flag = 0; 32 for(int j=0;j<n;j++) 33 { 34 if(str[j][len[j]]==DNA[i]) 35 { 36 flag = 1; 37 pos[j] = len[j]+1; 38 } 39 else 40 pos[j]=len[j]; 41 } 42 if(flag) 43 dfs(cnt+1,pos); 44 if(ans!=-1) 45 break; 46 } 47 } 48 49 int main() 50 { 51 int t; 52 cin>>t; 53 while(t--) 54 { 55 cin>>n; 56 int maxn = 0; 57 for(int i=0;i<n;i++) 58 { 59 cin>>str[i]; 60 size[i] = strlen(str[i]); 61 if(size[i]>maxn) 62 maxn = size[i]; 63 } 64 ans = -1; 65 deep = maxn; 66 int pos[10] = {0};//记录n个字符串目前匹配到的位置 67 while(1) 68 { 69 dfs(0,pos); 70 if(ans!=-1) 71 break; 72 deep++;//加深迭代 73 } 74 cout<<ans<<endl; 75 } 76 return 0; 77 }
第三题
AveryBoy又又又被关在一个n*m的迷宫里,这次还有了检查人员防止他逃跑。,并在迷宫的某些地方安装了带锁的门,钥匙藏在迷宫另外的某些地方。刚开始AveryBoy被关在(sx,sy)的位置,离开迷宫的门在(ex,ey)的位置。AveryBoy每分钟只能从一个坐标走到相邻四个坐标中的其中一个。检查人员每t分钟回地牢视察一次,若发现AveryBoy不在原位置便把他拎回去。经过若干次的尝试,AveryBoy已画出整个迷宫的地图。现在请你帮他计算能否再次成功逃出迷宫。只要在检查人员下次视察之前走到出口就算离开迷宫,如果检查人员回来的时候刚好走到出口或还未到出口都算逃亡失败。
Input
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为迷宫的地图,其中包括:
. 代表路
* 代表墙
@ 代表AveryBoy的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J
每组测试数据之间有一个空行。
. 代表路
* 代表墙
@ 代表AveryBoy的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J
每组测试数据之间有一个空行。
Output
针对每组测试数据,如果可以成功逃出迷宫,请输出需要多少分钟才能离开,如果不能则输出-1。
Sample Input
4 5 17
@A.B.
a*.*.
*..*^
c..b*
4 5 16
@A.B.
a*.*.
*..*^
c..b*
Sample Output
16
-1
第三题代码
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int maxn=20+10; 8 char map[maxn][maxn]; 9 int n,m,t; 10 bool vis[maxn][maxn][(1<<10)+10]; 11 int dx[]={-1,1,0,0}; 12 int dy[]={0,0,-1,1}; 13 struct Point 14 { 15 int x,y,step; 16 int key; 17 }; 18 queue<Point>q; 19 Point st; 20 bool check(int x,int y) 21 { 22 if(x>=1&&x<=n&&y>=1&&y<=m&&map[x][y]!='*') 23 return true; 24 return false; 25 } 26 int bfs() 27 { 28 while(!q.empty()) q.pop(); 29 memset(vis,false,sizeof(vis));//初始化 30 vis[st.x][st.y][st.key]=true; 31 st.key=st.step=0; 32 q.push(st); 33 Point cur,nex; 34 while(!q.empty()) 35 { 36 cur=q.front(); 37 q.pop(); 38 if(map[cur.x][cur.y]=='^')//判断是否到终点 39 return cur.step; 40 for(int i=0;i<4;i++) 41 { 42 nex.x=cur.x+dx[i]; 43 nex.y=cur.y+dy[i]; 44 nex.key=cur.key; 45 if(check(nex.x,nex.y)) 46 { 47 nex.step=cur.step+1; 48 if(nex.step>=t) 49 continue; 50 else if(map[nex.x][nex.y]>='A'&&map[nex.x][nex.y]<='Z')//判断是否为门 51 { 52 int temp=map[nex.x][nex.y]-'A'; 53 int nk=cur.key&1<<temp;//查询是否有钥匙 54 if(nk&&!vis[nex.x][nex.y][nex.key]) 55 { 56 vis[nex.x][nex.y][nex.key]=true;//走过 57 q.push(nex); 58 } 59 } 60 else if(map[nex.x][nex.y]>='a'&&map[nex.x][nex.y]<='z')//判断是否有钥匙 61 { 62 int temp=map[nex.x][nex.y]-'a'; 63 nex.key=cur.key|1<<temp;//查询是否有钥匙 64 if(!vis[nex.x][nex.y][nex.key]) 65 { 66 vis[nex.x][nex.y][nex.key]=true;//捡起 67 q.push(nex); 68 } 69 } 70 else 71 { 72 if(!vis[nex.x][nex.y][nex.key]) 73 { 74 vis[nex.x][nex.y][nex.key]=true; 75 q.push(nex); 76 } 77 } 78 } 79 } 80 } 81 return -1; 82 } 83 inline void print()//输入 84 { 85 char str[maxn]; 86 for(int i=1;i<=n;i++) 87 { 88 scanf("%s",str+1); 89 for(int j=1;j<=m;j++) 90 { 91 if(str[j]=='@') 92 { 93 st.x=i; 94 st.y=j; 95 map[i][j]=str[j]; 96 } 97 else map[i][j]=str[j]; 98 } 99 } 100 } 101 102 int main() 103 { 104 while(~scanf("%d%d%d",&n,&m,&t)) 105 { 106 print(); 107 int ans=bfs(); 108 printf("%d\n",ans); 109 } 110 return 0; 111 }
第四题是超级进阶版的迷宫 四维数组