UVa1448/LA4644 Hobby on Rails

题目链接

        本题是ICPC亚洲区域赛东京赛区2009年I 题。

测试数据

        https://icpc.iisf.or.jp/past-icpc/regional2009/InputsAndOutputs/

题意

        有一种轨道车玩具,h行w列矩形上的一个单元格即位一片轨道(2 ≤ h, w ≤ 6),轨道一共分4种(见下图),每片轨道可以90度倍数旋转。

        切换型轨道有直行/转弯两种状态。当玩具车从B/M端驶入时:如果此轨道为直行状态,则玩具车将从s端驶出,接下来此轨道切换为转弯状态;如果此轨道为转弯状态,则玩具车将从c端驶出,接下来此轨道切换为直行状态。当玩具车从S/C端驶入时,玩具车将从B/M端驶出并且此轨道状态不变。 

        切换型轨道的数量t满足:2 ≤ t ≤ 6。由于轨道可以旋转,要求合法旋转状态为: 每个切换型轨道的三端都直接或间接连接到了自己或其他切换型轨道。在合法旋转状态下,玩具车最终将沿着某个线路循环运动,可以求出此线路的周期T,它由(玩具车的初时位置, 玩具车的行驶方向, 所有切换型轨道的初时状态)三元组决定。

        给定矩形上轨道方格的初时信息,求所有旋转后合法状态下的周期最大值。如果没有合法旋转状态,输出0。

分析

        繁琐的搜索题目,要分多步搜索:

  1. 先得到所有合法旋转状态,枚举每个切换型轨道可能的旋转状态(边界上的轨道状态可以检验一下),再dfs拓展枚举他们实际需要延伸的周边轨道,验证要求是最终每个切换型轨道的三端都直接或间接连接到了自己或其他切换型轨道。
  2. 每得到一个合法旋转状态:                           
    • 先计算好每一个切换型轨道从三端驶出并驶入到下一个切换型轨道的信息:步数,下一切换型轨道驶入的端。
    • 再枚举所有切换型轨道的初时状态,然后依次选择一个切换型轨道的某一端作为初时驶出点,dfs求周期T,并更新答案。

AC代码

#include <iostream>
#include <cstring>
using namespace std;

#define N 8
char g[N][N]; short s[N][2], r[N][N], p[N][N], n, w, h, ans;
struct node {short x, y, c, d;} a[N][N][3]; bool vis1[N][N], vis2[N][N][3][1<<N] = {0};

bool check(short v) {
    for (short i=0; i<n; ++i, v>>=2) {
        short x = s[i][0], y = s[i][1], rot = r[x][y] = v&3;
        if (x==0 && ((g[x][y]=='L' && rot!=2) || (g[x][y]=='R' && rot!=3))) return false;
        if (x==h-1 && ((g[x][y]=='L' && rot!=0) || (g[x][y]=='R' && rot!=1))) return false;
        if (y==0 && ((g[x][y]=='L' && rot!=1) || (g[x][y]=='R' && rot!=2))) return false;
        if (y==w-1 && ((g[x][y]=='L' && rot!=3) || (g[x][y]=='R' && rot!=0))) return false;
    }
    return true;
}

bool check(short x, short y, short nx, short ny) {
    char c = g[nx][ny]; short rot = r[nx][ny];
    if (c == 'S') {
        if (nx!=x && !rot) return false;
        if (ny!=y && rot) return false;
    } else if (c == 'C') {
        if (nx<x && rot!=2 && rot!=3) return false;
        if (ny>y && rot!=0 && rot!=3) return false;
        if (nx>x && rot!=0 && rot!=1) return false;
        if (ny<y && rot!=1 && rot!=2) return false;
    } else if (c == 'L') {
        if (nx<x && rot==0) return false;
        if (ny>y && rot==1) return false;
        if (nx>x && rot==2) return false;
        if (ny<y && rot==3) return false;
    } else {
        if (nx<x && rot==1) return false;
        if (ny>y && rot==2) return false;
        if (nx>x && rot==3) return false;
        if (ny<y && rot==0) return false;
    }
    return true;
}

short check(short x, short y) {
    bool f[] = {true, true, true, true}; char c = g[x][y]; short rot = r[x][y], ret = 4;
    if (rot == 0) f[c=='L' ? 2 : 1] = false;
    else if (rot == 1) f[c=='L' ? 3 : 2] = false;
    else if (rot == 2) f[c=='L' ? 0 : 3] = false;
    else f[c=='L' ? 1 : 0] = false;
    short nx = x-1;
    if (f[0]) {
        if (!vis1[nx][y]) ret = 0;
        else if (!check(x, y, nx, y)) return -1;
    } else if (vis1[nx][y] && check(x, y, nx, y)) return -1;
    short ny = y+1;
    if (f[1]) {
        if (!vis1[x][ny]) ret = 1;
        else if (!check(x, y, x, ny)) return -1;
    } else if(vis1[x][ny] && check(x, y, x, ny)) return -1;
    nx = x+1;
    if (f[2]) {
        if (!vis1[nx][y]) ret = 2;
        else if (!check(x, y, nx, y)) return -1;
    } else if (vis1[nx][y] && check(x, y, nx, y)) return -1;
    ny = y-1;
    if (f[3]) {
        if (!vis1[x][ny]) ret = 3;
        else if (!check(x, y, x, ny)) return -1;
    } else if(vis1[x][ny] && check(x, y, x, ny)) return -1;
    return ret;
}

void build() {
    memset(p, -1, sizeof(p));
    for (short i=0; i<n; ++i) p[s[i][0]][s[i][1]] = i;
    for (short i=0; i<n; ++i) {
        short x = s[i][0], y = s[i][1], nx[3], ny[3], px[] = {x, x, x}, py[] = {y, y, y};
        node (&b)[3] = a[x][y]; b[0].c = b[1].c = b[2].c = 0;
        if (r[x][y] == 0) {
            if (g[x][y] == 'L') {
                nx[0] = x; ny[0] = y+1; nx[1] = x-1; ny[1] = y; nx[2] = x; ny[2] = y-1;
            } else {
                nx[0] = x+1; ny[0] = y; nx[1] = x; ny[1] = y-1; nx[2] = x-1; ny[2] = y;
            }
        } else if (r[x][y] == 1) {
            if (g[x][y] == 'L') {
                nx[0] = x+1; ny[0] = y; nx[1] = x; ny[1] = y+1; nx[2] = x-1; ny[2] = y;
            } else {
                nx[0] = x; ny[0] = y-1; nx[1] = x-1; ny[1] = y; nx[2] = x; ny[2] = y+1;
            }
        } else if (r[x][y] == 2) {
            if (g[x][y] == 'L') {
                nx[0] = x; ny[0] = y-1; nx[1] = x+1; ny[1] = y; nx[2] = x; ny[2] = y+1;
            } else {
                nx[0] = x-1; ny[0] = y; nx[1] = x; ny[1] = y+1; nx[2] = x+1; ny[2] = y;
            }
        } else {
            if (g[x][y] == 'L') {
                nx[0] = x-1; ny[0] = y; nx[1] = x; ny[1] = y-1; nx[2] = x+1; ny[2] = y;
            } else {
                nx[0] = x; ny[0] = y+1; nx[1] = x+1; ny[1] = y; nx[2] = x; ny[2] = y-1;
            }
        }
        for (short i=0; i<3; ++i) {
            x = nx[i]; y = ny[i]; short x0 = px[i], y0 = py[i];
            while (p[x][y] < 0) {
                ++b[i].c; short x1 = x, y1 = y;
                if (g[x][y] == 'S') {
                    x = (x<<1) - x0; y = (y<<1) - y0;
                } else {
                    if (x < x0) {
                        y = r[x][y]==2 ? y+1 : y-1;
                    } else if (x > x0) {
                        y = r[x][y]==1 ? y+1 : y-1;
                    } else if (y < y0) {
                        x = r[x][y]==2 ? x+1 : x-1;
                    } else {
                        x = r[x][y]==3 ? x+1 : x-1;
                    }
                }
                x0 = x1; y0 = y1;
            }
            ++b[i].c; b[i].x = x; b[i].y = y;
            if (r[x][y] == 0) b[i].d = g[x][y] == 'L' ? (y0<y ? 2 : x0<x) : (x0<x ? 2 : y0<y);
            else if (r[x][y] == 1) b[i].d = g[x][y] == 'L' ? (x0<x ? 2 : y0>y) : (y0>y ? 2 : x0<x);
            else if (r[x][y] == 2) b[i].d = g[x][y] == 'L' ? (y0>y ? 2 : x0>x) : (x0>x ? 2 : y0>y);
            else b[i].d = g[x][y] == 'L' ? (x0>x ? 2 : y0<y) : (y0<y ? 2 : x0>x);
        }
    }
}

void dfs(short x0, short y0, short d0, short s0, short x, short y, short d, short s, short c = 0) {
    if (vis2[x][y][d][s]) {
        if (x==x0 && y==y0 && d==d0 && s==s0) ans = max(ans, c);
        return;
    }
    node e = a[x][y][d]; short i = p[e.x][e.y]; vis2[x][y][d][s] = true;
    dfs(x0, y0, d0, s0, e.x, e.y, e.d<2 ? 2 : (s&(1<<i) ? 1 : 0), e.d<2 ? s : s^(1<<i), c+e.c);
    vis2[x][y][d][s] = false;
}

void dfs(short x, short y, short px, short py) {
    char c = g[x][y]; short nx, ny;
    if (c == 'S') {
        nx = (x<<1) - px; ny = (y<<1) - py;
        if (nx<0 || nx>=h || ny<0 || ny>=w) return;
        if (!vis1[nx][ny]) {
            vis1[nx][ny] = true;
            if (g[nx][ny] == 'S') {
                r[nx][ny] = r[x][y]; dfs(nx, ny, x, y);
            } else if (py < y) {
                r[nx][ny] = 0; dfs(nx, ny, x, y);
                r[nx][ny] = 3; dfs(nx, ny, x, y);
            } else if (py > y) {
                r[nx][ny] = 1; dfs(nx, ny, x, y);
                r[nx][ny] = 2; dfs(nx, ny, x, y);
            } else if (px < x) {
                r[nx][ny] = 0; dfs(nx, ny, x, y);
                r[nx][ny] = 1; dfs(nx, ny, x, y);
            } else {
                r[nx][ny] = 2; dfs(nx, ny, x, y);
                r[nx][ny] = 3; dfs(nx, ny, x, y);
            }
            vis1[nx][ny] = false;
            return;
        }
        if (!check(x, y, nx, ny)) return;
    } else if (c == 'C') {
        if (r[x][y] == 0) py<y ? (nx=x-1, ny=y) : (nx=x, ny=y-1);
        else if (r[x][y] == 1) py>y ? (nx=x-1, ny=y) : (nx=x, ny=y+1);
        else if (r[x][y] == 2) py>y ? (nx=x+1, ny=y) : (nx=x, ny=y+1);
        else py<y ? (nx=x+1, ny=y) : (nx=x, ny=y-1);
        if (nx<0 || nx>=h || ny<0 || ny>=w) return;
        if (!vis1[nx][ny]) {
            vis1[nx][ny] = true;
            if (g[nx][ny] == 'S') {
                r[nx][ny] = nx!=x; dfs(nx, ny, x, y);
            } else if (ny < y) {
                r[nx][ny] = 1; dfs(nx, ny, x, y);
                r[nx][ny] = 2; dfs(nx, ny, x, y);
            } else if (ny > y) {
                r[nx][ny] = 0; dfs(nx, ny, x, y);
                r[nx][ny] = 3; dfs(nx, ny, x, y);
            } else if (nx < x) {
                r[nx][ny] = 2; dfs(nx, ny, x, y);
                r[nx][ny] = 3; dfs(nx, ny, x, y);
            } else {
                r[nx][ny] = 0; dfs(nx, ny, x, y);
                r[nx][ny] = 1; dfs(nx, ny, x, y);
            }
            vis1[nx][ny] = false;
            return;
        }
        if (!check(x, y, nx, ny)) return;
    }
    short cc = n, f;
    for (short i=0; i<n; ++i) {
        short c = check(s[i][0], s[i][1]);
        if (c < 0) return;
        if (c < 4) cc = i, f = c;
    }
    if (cc == n) {
        build();
        for (short v=(1<<n)-1; v>=0; --v) for (short i=0; i<n; ++i) {
            dfs(s[i][0], s[i][1], 0, v, s[i][0], s[i][1], 0, v, 0);
            dfs(s[i][0], s[i][1], 1, v, s[i][0], s[i][1], 1, v, 0);
            dfs(s[i][0], s[i][1], 2, v, s[i][0], s[i][1], 2, v, 0);
        }
        return;
    }
    px = s[cc][0]; py = s[cc][1];
    if (f == 0) {
        vis1[x = px-1][y = py] = true;
        if (g[x][y] == 'S') {
            r[x][y] = 1; dfs(x, y, px, py);
        } else {
            r[x][y] = 2; dfs(x, y, px, py);
            r[x][y] = 3; dfs(x, y, px, py);
        }
        vis1[x][y] = false;
    } else if (f == 1) {
        vis1[x = px][y = py+1] = true;
        if (g[x][y] == 'S') {
            r[x][y] = 0; dfs(x, y, px, py);
        } else {
            r[x][y] = 0; dfs(x, y, px, py);
            r[x][y] = 3; dfs(x, y, px, py);
        }
        vis1[x][y] = false;
    } else if (f == 2) {
        vis1[x = px+1][y = py] = true;
        if (g[x][y] == 'S') {
            r[x][y] = 1; dfs(x, y, px, py);
        } else {
            r[x][y] = 0; dfs(x, y, px, py);
            r[x][y] = 1; dfs(x, y, px, py);
        }
        vis1[x][y] = false;
    } else {
        vis1[x = px][y = py-1] = true;
        if (g[x][y] == 'S') {
            r[x][y] = 0; dfs(x, y, px, py);
        } else {
            r[x][y] = 1; dfs(x, y, px, py);
            r[x][y] = 2; dfs(x, y, px, py);
        }
        vis1[x][y] = false;
    }
}

int solve() {
    bool ok = true; ans = 0;
    for (short i=n=0; i<h; ++i) for (short j=0; j<w; ++j) {
        cin >> g[i][j];
        if (g[i][j]=='L' || g[i][j]=='R') {
            s[n][0] = i; s[n++][1] = j;
            if ((i==0 || i==h-1) && (j==0 || j==w-1)) ok = false;
        }
    }
    if (!ok) return ans;
    memset(vis1, 0, sizeof(vis1));
    for (short i=0; i<n; ++i) vis1[s[i][0]][s[i][1]] = true;
    for (short v=(1<<n<<n)-1; v>=0; --v) if (check(v)) {
        dfs(s[0][0], s[0][1], s[0][0], s[0][1]);
    }
    return ans;
}

int main() {
    while (cin>>w>>h && w) cout << solve() << endl;
    return 0;
}
基于SSM框架的网红酒店预定系统,是一个集前台用户操作和后台管理员管理于一体的综合性平台。该系统旨在通过信息化手段,提高酒店预订的效率和用户体验。 系统的主要功能模块包括: 1. **用户管理**:允许用户注册、登录,查看个人信息,以及修改个人资料和密码。 2. **客房管理**:管理员可以添加、删除或修改客房信息,包括房型、价格、设施等。 3. **预订管理**:用户可以浏览可用房型,进行预订操作,管理员则可以管理预订订单,包括确认预订、办理入住和退房等。 4. **退订管理**:用户和管理员都可以处理预订的取消,管理员可以审核退订请求。 5. **系统管理**:管理员可以进行系统设置,包括权限管理、日志查看等。 系统的设计考虑了用户体验和管理员的便捷性,通过SSM框架的灵活性和MySQL数据库的稳定性,实现了数据的高效管理和处理。系统的前端界面友好,操作流程简洁,能够满足用户快速预订和查询的需求。同时,系统的后台管理功能强大,能够为管理员提供全面的数据分析和决策支持。 此外,系统还具有高度的安全性和稳定性,通过角色权限控制,确保了数据的安全性和系统的稳定运行。系统的开发和设计,不仅提升了网红酒店的品牌形象,也为用户带来了便捷的预订体验,进一步推动了酒店行业的信息化发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值