zoukankan      html  css  js  c++  java
  • C. Tesla (模拟 + 思维)

    题目:传送门

    题意:在一个 4 * n 的矩阵里,有 k 辆车,一开始所有的车都在第二和第三行,第一和第四行是车位,你一秒钟只能移动一辆车一步,问你有没有可能在 20000 秒内,将所有的车停到对应的车位上。

    n <= 50, k <= 2n

    思路:

    我们首先将那些车位就在眼前的车,停进去,这时只要第二和第三行有一个空位,就可以保证所有车都能听到对应的车位上。

    我们只要让所有车都逆时针移动,然后每移动一圈就把对应的可以停车的停进去就可以了。

    #include <bits/stdc++.h>
    #define LL long long
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF INT_MAX
    #define inf LLONG_MAX
    #define PI acos(-1)
    using namespace std;
    
    const int N = 1e6 + 5, mod = 1e9 + 7;
    
    int nx[4] = {1, -1, 0, 0};
    int ny[4] = {0, 0, 1, -1};
    
    LL ksm(LL a, LL b) {
        LL ans = 1;
        while(b) {
            if(b & 1) ans = ans * a % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return ans;
    }
    
    int a[5][100];
    
    pair < int, int >ans[N];
    int id[N], tot, n, k;
    
    bool judge() {
        rep(i, 1, n) {
            if(!a[2][i] || !a[3][i]) return true;
        }
        return false;
    }
    
    void stop() {
        rep(i, 1, n) {
            if(a[2][i] == a[1][i] && a[1][i] != 0) {
                ans[++tot] = make(1, i);
                id[tot] = a[2][i];
                a[2][i] = 0;
                k--;
            }
            if(a[3][i] == a[4][i] && a[3][i] != 0) {
                ans[++tot] = make(4, i);
                id[tot] = a[3][i];
                a[3][i] = 0;
                k--;
            }
        }
    }
    
    void trun(int x, int y) {
        int nowx = x, nowy = y;
        if(x == 2) {
            while(y < n) {
                y++;
                if(a[x][y]) {
                    ans[++tot] = make(x, y - 1);
                    id[tot] = a[x][y];
                }
                a[x][y - 1] = a[x][y];
            }
            x++;
            if(a[x][y]) {
                ans[++tot] = make(x - 1, y);
                id[tot] = a[x][y];
            }
            a[x - 1][y] = a[x][y];
            while(y > 1) {
                y--;
                if(a[x][y]) {
                    ans[++tot] = make(x, y + 1);
                    id[tot] = a[x][y];
                }
                a[x][y + 1] = a[x][y];
            }
            x--;
    
            if(x == nowx && y == nowy) return ;
    
            if(a[x][y]) {
                ans[++tot] = make(x + 1, y);
                id[tot] = a[x][y];
            }
            a[x + 1][y] = a[x][y];
            while(y < nowy - 1) {
                y++;
                if(a[x][y]) {
                    ans[++tot] = make(x, y - 1);
                    id[tot] = a[x][y];
                }
                a[x][y - 1] = a[x][y];
            }
        }
        else {
            while(y > 1) {
                y--;
                if(a[x][y]) {
                    ans[++tot] = make(x, y + 1);
                    id[tot] = a[x][y];
                }
                a[x][y + 1] = a[x][y];
            }
            x--;
            if(a[x][y]) {
                ans[++tot] = make(x + 1, y);
                id[tot] = a[x][y];
            }
            a[x + 1][y] = a[x][y];
            while(y < n) {
                y++;
                if(a[x][y]) {
                    ans[++tot] = make(x, y - 1);
                    id[tot] = a[x][y];
                }
                a[x][y - 1] = a[x][y];
            }
            x++;
            if(x == nowx && y == nowy) return ;
            if(a[x][y]) {
                ans[++tot] = make(x - 1, y);
                id[tot] = a[x][y];
            }
            a[x - 1][y] = a[x][y];
            while(y > nowy + 1) {
                y--;
                if(a[x][y]) {
                    ans[++tot] = make(x, y + 1);
                    id[tot] = a[x][y];
                }
                a[x][y + 1] = a[x][y];
            }
        }
    
    }
    
    void solve() {
    
        scanf("%d %d", &n, &k);
    
        rep(i, 1, 4) rep(j, 1, n) scanf("%d", &a[i][j]);
    
        stop();
        if(judge() == false) { puts("-1"); return ; }
    
        int x, y;
        rep(i, 1, n) {
            if(a[2][i] == 0) {
                x = 2; y = i; break;
            }
            if(a[3][i] == 0) {
                x = 3; y = i; break;
            }
        }
    
        while(k) {
            trun(x, y);
            stop();
            if(x == 3 && y == n) x = 2;
            else if(x == 2 && y == 1) x = 3;
            else if(x == 3) y++;
            else if(x == 2) y--;
        }
    
        printf("%d
    ", tot);
        rep(i, 1, tot) printf("%d %d %d
    ", id[i], ans[i].first, ans[i].second);
    
    }
    
    
    int main() {
    
        solve();
    
    
        return 0;
    }
    一步一步,永不停息
  • 相关阅读:
    bzoj3380+3381+3382+3383 Usaco2004 Open
    浅谈树链剖分(C++、算法、树结构)
    小学奥数 最大公约数与最小公倍数
    小学奥数 质数的和与积
    小学奥数 分苹果
    小学奥数 连乘积末尾0的个数
    小学奥数 李白的酒
    小学奥数 回文数个数
    小学奥数 等差数列末项计算
    小学奥数 地球人口承载力估计
  • 原文地址:https://www.cnblogs.com/Willems/p/12523624.html
Copyright © 2011-2022 走看看