旋转游戏 “井”

 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

每组测试数据之间有一个空行。

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 }

 

第四题是超级进阶版的迷宫 四维数组

 

转载于:https://www.cnblogs.com/jzzb/p/9372833.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值