2 solutions

  • 1
    @ 2026-4-3 19:35:12
    
    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int n, m;
    char grid[600][600];
    int dist[600][600];
    bool vis[600][600];
    struct node
    {
        int x, y;
    };
    int dx[4] = {-1, -1, 1, 1};
    int dy[4] = {-1, 1, 1, -1};
    int gx[4] = {-1, -1, 0, 0};
    int gy[4] = {-1, 0, 0, -1};
    char expect[4] = {'\\', '/', '\\', '/'};
    int main()
    {
        cin >> n >> m;
        for(int i = 0; i < n; ++i)
    	{
            for(int j = 0; j < m; ++j)
    		{
                cin >> grid[i][j];
            }
        }
        if((n + m) % 2 != 0)
    	{
            cout << "NO SOLUTION" << endl;
            return 0;
        }
        memset(dist, 0x3f, sizeof(dist));
        memset(vis, 0, sizeof(vis));
        deque<node> dq;
        dist[0][0] = 0;
        dq.push_back({0, 0});
        while (!dq.empty())
    	{
            node cur = dq.front();
            dq.pop_front();
            int x = cur.x, y = cur.y;
            if (vis[x][y])
    		{
            	continue;
    		}
            vis[x][y] = true;
            if (x == n && y == m)
    		{
            	break;
    		}
            for (int i = 0; i < 4; ++i)
    		{
                int nx = x + dx[i];
                int ny = y + dy[i];
                if (nx >= 0 && nx <= n && ny >= 0 && ny <= m)
    			{
                    int r = x + gx[i];
                    int c = y + gy[i];
                    int weiht;
                    if(grid[r][c]==expect[i])
                    {
                    	weight=0;
    				}
    				else
    				{
    					weight=1;
    				}
                    if (dist[nx][ny] > dist[x][y] + weight)
    				{
                        dist[nx][ny] = dist[x][y] + weight;
                        if (weight == 0)
    					{
                            dq.push_front({nx, ny});
                        }
    					else
    					{
                            dq.push_back({nx, ny});
                        }
                    }
                }
            }
        }
        if (dist[n][m] == INF)
    	{
        	cout << "NO SOLUTION" << endl;
    	}
        else
    	{
        	cout << dist[n][m] << endl;
    	}
        return 0;
    }
    
  • -9
    @ 2026-4-3 19:26:16
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 505;
    const int INF = 0x3f3f3f3f;
    
    // n, m 为格子行列数
    int n, m;
    char grid[MAXN][MAXN];
    int dist[MAXN][MAXN];
    bool vis[MAXN][MAXN];
    
    // 结构体存储顶点坐标
    struct Node {
        int x, y;
    };
    
    // 方向数组:四个斜对角方向(顶点的移动)
    int dx[4] = {-1, -1, 1, 1};
    int dy[4] = {-1, 1, 1, -1};
    
    // 对应方向上,格子的相对坐标(判断该路径属于哪个格子)
    int gx[4] = {-1, -1, 0, 0};
    int gy[4] = {-1, 0, 0, -1};
    
    // 对应方向上,期望的电线形状
    char expect[4] = {'\\', '/', '\\', '/'};
    
    void solve() {
        cin >> n >> m;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                cin >> grid[i][j];
            }
        }
    
        // 奇偶性剪枝:起点 (0,0) 到终点 (n,m) 的横纵坐标之和奇偶性必须一致
        // 每次移动 dx, dy 都是 1 或 -1,坐标之和的奇偶性变化是确定的
        if ((n + m) % 2 != 0) {
            cout << "NO SOLUTION" << endl;
            return;
        }
    
        // 初始化
        memset(dist, 0x3f, sizeof(dist));
        memset(vis, 0, sizeof(vis));
        deque<Node> dq;
    
        // 起点
        dist[0][0] = 0;
        dq.push_back({0, 0});
    
        while (!dq.empty()) {
            Node cur = dq.front();
            dq.pop_front();
    
            int x = cur.x, y = cur.y;
    
            // 如果已经处理过该点,跳过(Dijkstra 思想)
            if (vis[x][y]) continue;
            vis[x][y] = true;
    
            // 终点提前退出(可选优化)
            if (x == n && y == m) break;
    
            for (int i = 0; i < 4; ++i) {
                int nx = x + dx[i];
                int ny = y + dy[i];
    
                // 判断顶点是否越界
                if (nx >= 0 && nx <= n && ny >= 0 && ny <= m) {
                    // 确定当前路径经过的格子坐标
                    int r = x + gx[i];
                    int c = y + gy[i];
                    
                    // 计算边权:方向匹配则为0,不匹配则需要旋转,权值为1
                    int weight = (grid[r][c] == expect[i] ? 0 : 1);
    
                    if (dist[nx][ny] > dist[x][y] + weight) {
                        dist[nx][ny] = dist[x][y] + weight;
                        // 0-1 BFS 核心:0 权边插队首,1 权边插队尾
                        if (weight == 0) {
                            dq.push_front({nx, ny});
                        } else {
                            dq.push_back({nx, ny});
                        }
                    }
                }
            }
        }
    
        if (dist[n][m] == INF) cout << "NO SOLUTION" << endl;
        else cout << dist[n][m] << endl;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
    
        solve();
    
        return 0;
    }
    
  • 1

「一本通 1.4 例 1」电路维修[BalticOI 2011 Day1] Switch the Lamp On 电路维修

Information

ID
301
Time
150ms
Memory
125MiB
Difficulty
7
Tags
# Submissions
35
Accepted
9
Uploaded By