码迷,mamicode.com
首页 > 其他好文 > 详细

Atcoder Beginner Contest 184

时间:2020-11-26 15:23:49      阅读:14      评论:0      收藏:0      [点我收藏+]

标签:遍历   contest   bfs   names   步骤   超时   mem   clu   memset   

Atcoder Beginner Contest 184

A-Determinant

Solution:

输出\(ad-bc\)

#include <iostream>
using namespace std;

int main()
{
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    cout << a * d - b * c << endl;
    return 0;
}
B-Quizzes

Solution:

遍历整个字符串,遇到‘x‘减1,遇到’o‘加1,注意中间值不能小于0.

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

const int maxn = 211111;

int n, x;
char str[maxn];

int main()
{
    cin >> n >> x;
    cin >> str;
    for(int i = 0; i < n; ++i) {
        if(str[i] == ‘o‘) x++;
        else x = max(0, x - 1);
    }
    cout << x << endl;
    return 0;
}
C-Super Ryuma

Solution:

分析一个位置可以一次到达的点可知有两种情况:

  • 经过该点的四条对角线上的所有点都可一步到达
  • 该点周围,到该点的曼哈顿距离\((|x_1- x_2| + |y_1-y_2|)\)小与3的点,可以直接到达。

考虑这两种到达方式可知:

  • 任意两点满足上述条件,需要一步
  • 可以通过一次步骤一和一次步骤二到达,可以通过两次不同步骤一到达的均为两步
  • 其余均为三步(先通过两步走到附近,在用一次方法二到达)
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

int main()
{
    long long a, b, c, d;
    cin >> a >> b >> c >> d;
    if(a == c && b == d) {
        cout << 0 << endl;
        return 0;
    }
    if(a + b == c + d || a - b == c - d || abs(a - c) + abs(b - d) <= 3) cout << 1 << endl;
    else {
        bool fl = false;
        for(int i = -3; i <= 3; ++i) {
            for(int j = -3; j <= 3; ++j) {
                if(i + j > 3) continue;
                int x = a + i;
                int y = b + j;
                if(x + y == c + d || x - y == c - d || abs(x - c) + abs(y - d) <= 3) fl = true;
            }
        }
        if((c + d - b + a) % 2 == 0 && (c + d + b - a) % 2 == 0) fl = true;
        if((b + a - d + c) % 2 == 0 && (b + a + d - c) % 2 == 0) fl = true;
        cout << (fl ? 2 : 3) << endl;
    }
    return 0;
}
D-increment of coins

Solution:

dfs搜索每种种情况的所需步数,加入记忆化搜索优化(否则超时)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
using namespace std;

const int maxn = 111;

double dp[maxn][maxn][maxn];
int A, B, C;

double dfs(int a, int b, int c, int dep)
{
    if(dp[a][b][c] != 0) return dp[a][b][c]; 
    if(a >= 100 || b >= 100 || c >= 100) return dp[a][b][c] = dep;
    double res = 0, sum = a + b + c;
    if(a) {
        res += a / sum * dfs(a + 1, b, c, dep + 1);
    }
    if(b) {
        res += b / sum * dfs(a, b + 1, c, dep + 1);
    }
    if(c) {
        res += c / sum * dfs(a, b, c + 1, dep + 1);
    }
    return dp[a][b][c] = res;
}

int main()
{
    cin >> A >> B >> C;
    memset(dp, 0, sizeof(dp));
    cout << setprecision(7) << dfs(A, B, C, 0) << endl;
    return 0;
}
E-Third Avenue

Solution:

bfs,注意已经扩展过的字母在任何其他位置都不需要再扩展,因此直接删除这个字符的扩展即可(否则超时)

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
#include <list>
using namespace std;

const int maxn = 2111;
const int mov[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

char mp[maxn][maxn];
int vis[maxn][maxn];
list<pair<int, int>> box[30];
int h, w;

int bfs(pair<int, int> be, pair<int, int> ed)
{
    if(be == ed) return 0;
    queue<pair<pair<int, int>, int>> que;
    que.push(make_pair(be, 0));
    memset(vis, 0, sizeof(vis)); vis[be.first][be.second] = 1;
    while(!que.empty()) {
        auto now = que.front(); que.pop();
        if(now.first == ed) return now.second;
        int x = now.first.first;
        int y = now.first.second;
        int sp = now.second;
        for(int i = 0; i < 4; ++i) {
            int nx = x + mov[i][0];
            int ny = y + mov[i][1];
            if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
            if(vis[nx][ny] || mp[nx][ny] == ‘#‘) continue;
            vis[nx][ny] = 1;
            que.push(make_pair(make_pair(nx, ny), sp + 1));
        }
        if(mp[x][y] >= ‘a‘ && mp[x][y] <= ‘z‘) {
            vector<list<pair<int, int>>::iterator> mid;
            for(list<pair<int, int>>::iterator it = box[int(mp[x][y] - ‘a‘)].begin(); it != box[int(mp[x][y] - ‘a‘)].end(); it++) {
                que.push(make_pair(*it, sp + 1));
                mid.push_back(it);
            }
            for(auto k : mid) box[int(mp[x][y] - ‘a‘)].erase(k);
        }
    }
    return -1;
}

int main()
{
    cin >> h >> w;
    for(int i = 0; i < h; ++i) {
        cin >> mp[i];
    }
    pair<int, int> S, G;
    for(int i = 0; i < h; ++i) {
        for(int j = 0; j < w; ++j) {
            if(mp[i][j] == ‘S‘) {
                S = make_pair(i, j);
            }
            else if(mp[i][j] == ‘G‘) {
                G = make_pair(i, j);
            }
            else if(mp[i][j] >= ‘a‘ && mp[i][j] <= ‘z‘) {
                box[int(mp[i][j] - ‘a‘)].emplace_back(i, j);
            }
        }
    }
    cout << bfs(S, G) << endl;
    return 0;
}
F-Programming Contest

Solution:

数据为40个,因此直接搜索会超时,但是如果数据降到20,我们就可以用dfs或者集合子集枚举的方式求出所有可能解,因此这题将数据分成前后两半考虑,分别求出所有可能之后,二分求出最后答案。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std;

typedef long long ll;

const int maxn = 44;

ll a1[maxn], a2[maxn], n, t;
vector<ll> b1, b2;

int main()
{
    freopen("in.in", "r", stdin);
    cin >> n >> t;
    int l1 = 0, l2 = 0;
    for(int i = 0; i < n / 2; ++i) {
        cin >> a1[i];
        l1++;
    }
    for(int i = n / 2; i < n; ++i) {
        cin >> a2[i - n / 2];
        l2++;
    }
    for(int i = 0; i < (1 << l1); ++i) {
        ll cost = 0;
        for(int j = 0; j < l1; ++j) {
            if(i & (1 << j)) cost += a1[j];
        }
        if(cost <= t)
        b1.push_back(cost);
    }
    for(int i = 0; i < (1 << l2); ++i) {
        ll cost = 0;
        for(int j = 0; j < l2; ++j) {
            if(i & (1 << j)) cost += a2[j];
        }
        if(cost <= t)
        b2.push_back(cost);
    }
    sort(b1.begin(), b1.end());
    sort(b2.begin(), b2.end());
    l1 = int(unique(b1.begin(), b1.end()) - b1.begin());
    l2 = int(unique(b2.begin(), b2.end()) - b2.begin());
    ll ans = 0;
    for(int i = 0; i < l1; ++i) {
        ll k = b1[i];
        int ad = int(upper_bound(b2.begin(), b2.begin() + l2, t - k) - b2.begin());
        ad--;
        if(ad >= 0 && b2[ad] + k <= t) ans = max(ans, b2[ad] + k); 
    }
    cout << ans << endl;
    return 0;
}

Atcoder Beginner Contest 184

标签:遍历   contest   bfs   names   步骤   超时   mem   clu   memset   

原文地址:https://www.cnblogs.com/LeafLove/p/14025745.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!