Facebook Hacker Cup 2015 qualification round解题报告

题目可以戳:https://www.facebook.com/hackercup/problems.php?pid=582062045257424&round=742632349177460

墙高,准备好梯子。



众所周知,资格赛肯定是恨水的啦。。。于是又水了一发满分,希望接下来不要爆零。。。


A. Cooking the Books

把所有的字符串都构造出来,然后排序就行了。。不多说

#include <vector>
#include <list>
#include <limits.h>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <stdlib.h>
#include <cassert>
#define FOR(i, n) for (int i = 0; i < n; ++i)
using namespace std;

int main() {
    int T;
    cin >> T;
    FOR(tt, T) {
        cout << "Case #" << tt + 1 << ": ";
        string number;
        cin >> number;
        vector<string> res;
        res.emplace_back(number);
        for (int i = 0; i < number.size(); ++i)
            for (int j = i + 1; j < number.size(); ++j) {
                if (i == 0 && number[j] == '0') continue;
                string tmp = number;
                swap(tmp[i], tmp[j]);
                res.emplace_back(tmp);
            }
        sort(res.begin(), res.end());
        cout << res[0] << " " << res[res.size() - 1] << endl;
    }
    return 0;
}


B. 注意N的范围是比较小的,于是暴力枚举并验证是否符合要求就行了。

#include <vector>
#include <list>
#include <limits.h>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <stdlib.h>
#include <cassert>
#include <tuple>
#define FOR(i, n) for (int i = 0; i < n; ++i)
using namespace std;

int main() {
    int T, P, C, F, N;
    cin >> T;
    FOR(tt, T) {
        cout << "Case #" << tt + 1 << ": ";
        bool ok = false;
        cin >> P >> C >> F;
        tuple<int, int, int> goal = make_tuple(P, C, F);
        cin >> N;
        vector<tuple<int, int, int> > v;
        FOR(i, N) {
            cin >> P >> C >> F;
            v.push_back(make_tuple(P, C, F));
        }
        FOR(i, 1 << N) {
            tuple<int, int, int> cur = make_tuple(0, 0, 0);
            for (int j = 0; j < N; ++j) {
                if ((1<<j)&i) {
                    get<0>(cur) += get<0>(v[j]);
                    get<1>(cur) += get<1>(v[j]);
                    get<2>(cur) += get<2>(v[j]);
                }
            }
            if (cur == goal) { ok = true; break; }
        }
        if (ok) cout << "yes" << endl;
        else cout << "no" << endl;
    }
}


C. 其实就是广度优先搜索稍微变形了一下,状态只包括坐标本身是不够的,还需要把laser的朝向包括进去,只要明白这一点,就很简单了。

#include <vector>
#include <list>
#include <limits.h>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <stdlib.h>
#include <cassert>
#include <tuple>
#define FOR(i, n) for (int i = 0; i < n; ++i)
using namespace std;

const int dir_x[] = {0, -1, 0, 1};
const int dir_y[] = {-1, 0, 1, 0};
const char dir[] = {'<', '^', '>', 'v'};

int get_index(const char d) {
    FOR(i, 4) if (dir[i] == d) return i;
    return -1;
}

int main() {
    int T, row, col;
    pair<int, int> start, goal;
    cin >> T;
    FOR(tt, T) {
        cout << "Case #" << tt + 1 << ": ";
        cin >> row >> col;
        vector<string> maze;
        FOR(i, row) {
            string t;
            cin >> t;
            maze.emplace_back(t);
        }
        FOR(i, row) FOR(j, col) {
            if (maze[i][j] == 'S') { start = {i, j}; maze[i][j] = '.'; }
            if (maze[i][j] == 'G') { goal = {i, j}; maze[i][j] = '.'; }
        }
        set<tuple<int, int, int> > danger;
        FOR(i, row) FOR(j, col) {
            int ind = get_index(maze[i][j]);
            if (ind < 0) continue;
            FOR(k, 4) {
                int pos = (k + ind) % 4;
                int curx = i, cury = j;
                while (true) {
                    curx += dir_x[pos]; cury += dir_y[pos];
                    // out of boundary
                    if (curx < 0 || curx >= row || cury < 0 || cury >= col) break;
                    // wall
                    if (maze[curx][cury] == '#') break;
                    // laser
                    if (get_index(maze[curx][cury]) >= 0) break;
                    danger.insert(make_tuple(curx, cury, k));
                }
            }
        }
        bool ok = false;
        queue<tuple<int, int, int> > q;
        map<tuple<int, int, int>, int> res;
        auto ft = make_tuple(start.first, start.second, 0);
        q.push(ft); res[ft] = 0;
        int step;
        while (!q.empty()) {
            auto tp = q.front(); q.pop();
            int x = get<0>(tp), y = get<1>(tp), rem = get<2>(tp);
            if (make_pair(x, y) == goal) { ok = true; step = res[tp]; break; }
            int nrem = (rem + 1) % 4;
            FOR(i, 4) {
                int nx = x + dir_x[i], ny = y + dir_y[i];
                auto cand = make_tuple(nx, ny, nrem);
                if (nx < 0 || nx >= row || ny < 0 || ny >= col) continue;
                if (maze[nx][ny] == '#') continue;
                if (get_index(maze[nx][ny]) >= 0) continue;
                if (danger.find(cand) != danger.end()) continue;
                if (res.find(cand) != res.end() && res[tp] + 1 >= res[cand]) continue;
                q.push(cand); res[cand] = res[tp] + 1;
            }
        }
        if (ok) cout << step << endl;
        else cout << "impossible" << endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值