CUGB的一场周赛

it2022-05-09  37

周三要考试,可是根本就踏实不下来复习,毕设也静不下心弄了。于是就玩玩比赛了,晚上12点还有一场CF,到时候再玩个1个多小时去睡觉。

说说我周赛做的两道题吧:

Open the Lock

一个四位数变成另一个四位数,要求的操作有三种:

1. 对任意一位加1,如果大于9,回到1

2. 对任意一位减1,如果小于1,回到9

3. 交换相邻两位的数字,最左边和最右边不算相邻

可以知道状态空间为9*9*9*9<10^4,直接BFS搞就可以了,因为我大量使用STL,导致TLE了,后来改成int,就AC了,代码如下:

#include <iostream> #include <string> #include <algorithm> #include <vector> #include <set> using namespace std;   const int MAX = 2005;   //string a, b; int a, b;   int hash[100 * 100]; int ten[4] = {1, 10, 100, 1000};   int GetHash(int x) { return x; }   int Add(int x, int i) { int t = (x / ten[i]) % 10; if(t < 9) return x + ten[i]; else return x - t * ten[i] + ten[i]; }   int Sub(int x, int i) { int t = (x / ten[i]) % 10; if(t > 1) return x - ten[i]; else return x - t * ten[i] + 9 * ten[i]; }   int Swp(int x, int i) { int t1 = (x / ten[i]) % 10; int t2 = (x / ten[i + 1]) % 10; return x - t1 * ten[i] - t2 * ten[i + 1] + t2 * ten[i] + t1 * ten[i + 1]; }   int go() { vector<int> ans; vector<int> Q; //set<string> one; Q.push_back(a); ans.push_back(0); //one.insert(a); memset(hash, 0, sizeof(hash)); hash[GetHash(a)] = 1;   for(int i = 0; i < Q.size(); i++) { //printf("$%d\n", Q[i]); if(Q[i] == b) { //printf("%d %d\n", Q[i], b); return ans[i]; } for(int j = 0; j < 4; j++) { int strAdd = Add(Q[i], j); int strSub = Sub(Q[i], j); //if(one.find(strAdd) == one.end()) if(hash[GetHash(strAdd)] == 0) { //one.insert(strAdd); Q.push_back(strAdd); ans.push_back(ans[i] + 1); hash[GetHash(strAdd)] = 1; } //else return ans[i] + 1; //if(one.find(strSub) == one.end()) if(hash[GetHash(strSub)] == 0) { //one.insert(strSub); Q.push_back(strSub); ans.push_back(ans[i] + 1); hash[GetHash(strSub)] = 1; } //else return ans[i] + 1; if(j < 3) { int strSwp = Swp(Q[i], j); //if(one.find(strSwp) == one.end()) if(hash[GetHash(strSwp)] == 0) { //one.insert(strSwp); Q.push_back(strSwp); ans.push_back(ans[i] + 1); hash[GetHash(strSwp)] = 1; } // else return ans[i] + 1; } } } }   int main() { int T; scanf("%d", &T); while(T--) { //cin >> a >> b; scanf("%d%d", &a, &b); printf("%d\n", go()); } }

 

诡异的楼梯

一张20*20的地图,上满有障碍点,非障碍点,楼梯三种格子,起点、终点落在非障碍点上,梯子每分钟改变一个朝向(横着,竖着),从起点到终点,四个方向,问说最少的步数,走楼梯的话,就一下子跨两格。

设置一个这样的状态(x,y,step),花费的空间也就20*20*400左右,然后去BFS,这样是可以AC的,有趣的是,我觉得只要存step的奇偶性就行了,也就是这样的状态(x,y,step%2),我觉得这样是对的,但一时不知道怎么严谨说明,大概就是,如果先扩展到一个奇数步的节点的话,那么这个就是奇数所能到达的最小的走法了,看着代码虽然100+行,但是自己看了看,发现其实也没啥东西,代码如下:

#include <iostream> #include <string> #include <algorithm> #include <vector> #include <set> using namespace std;   const int MAX = 25;   int m, n, sx, sy, ex, ey; char mm[MAX][MAX];   int hash[405 * 410];   class CNODE { public:     int x, y, t; public:     CNODE() {}     CNODE(int _x, int _y, int _t)         : x(_x), y(_y), t(_t) {}     int GetHash()     {         int res = 0;         res += (x * 20 + y);         res = res * 410 + (t % 2);         //res = res * 410 + t;         return res;     } };   int go() {     memset(hash, 0, sizeof(hash));     vector<CNODE> Q;     Q.push_back(CNODE(sx, sy, 0));     hash[Q[0].GetHash()] = 1;         for(int i = 0; i < Q.size(); i++)     {         int x = Q[i].x;         int y = Q[i].y;         int t = Q[i].t;           if(x == ex && y == ey) return t;           CNODE dd = CNODE(x, y, t + 1);         if(hash[dd.GetHash()] == 0)         {             hash[dd.GetHash()] = 1;             Q.push_back(dd);         }           for(int j = -1; j <= 1; j++) for(int k = -1; k <= 1; k++)             if(j * j + k * k == 1)             {                 int dx = x + j;                 int dy = y + k;                 if(dx < 0 || dx >= m || dy < 0 || dy >= n)                     continue;                 if(mm[dx][dy] == '*') continue;                   CNODE dq;                 if(mm[dx][dy] == '.' || mm[dx][dy] == 'T' || mm[dx][dy] == 'S')                 {                     dq = CNODE(dx, dy, t + 1);                     if(hash[dq.GetHash()] == 0)                     {                         hash[dq.GetHash()] = 1;                         Q.push_back(dq);                     }                     if(dx == ex && dy == ey) return t + 1;                 }                 else                 {                     if((mm[dx][dy] == '|' && k == 0 && t % 2 == 0) ||                         (mm[dx][dy] == '-' && k == 0 && t % 2 == 1))                     {                         if(dx + j >= 0 && dx + j < m)                         {                             dq = CNODE(dx + j, dy, t + 1);                             if(hash[dq.GetHash()] == 0)                             {                                 hash[dq.GetHash()] = 1;                                 Q.push_back(dq);                             }                             if(dx == ex && dy == ey) return t + 1;                         }                     }                     if((mm[dx][dy] == '-' && j == 0 && t % 2 == 0) ||                         (mm[dx][dy] == '|' && j == 0 && t % 2 == 1))                     {                         if(dy + k >= 0 && dy + k < n)                         {                             dq = CNODE(dx, dy + k, t + 1);                             if(hash[dq.GetHash()] == 0)                             {                                 hash[dq.GetHash()] = 1;                                 Q.push_back(dq);                             }                             if(dx == ex && dy == ey) return t + 1;                         }                     }                 }             }     }     printf("no\n"); }   int main() {     while(scanf("%d%d", &m, &n) != EOF)     {         for(int i = 0; i < m; i++)         {             scanf("%s", mm[i]);             for(int j = 0; j < n; j++)             {                 if(mm[i][j] == 'S') sx = i, sy = j;                 if(mm[i][j] == 'T') ex = i, ey = j;             }         }         printf("%d\n", go());     } }

转载于:https://www.cnblogs.com/litstrong/archive/2011/03/20/1989792.html


最新回复(0)