CUGB的一场周赛

周三要考试,可是根本就踏实不下来复习,毕设也静不下心弄了。于是就玩玩比赛了,晚上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());
    }
}

诡异的楼梯

C6-1003

一张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/p/1989792.html