2020年牛客算法入门课练习赛3

题目链接:https://ac.nowcoder.com/acm/contest/6164#question
题解链接:

A - 胖胖的牛牛

state 表示已经转了几次向,pre 记录的是当前的方向(上下表示-1,左右表示1),如果 pre * now == -1,表示转向了,转移时 state + 1

#include 
using namespace std;
const int N = 105, INF = 0x3f3f3f3f;

char ma[N][N];
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int n, res = INF;
int sx, sy, gx, gy;
bool vis[N][N];

void dfs(int x, int y, int state, int pre)
{
	// 不剪枝会TLE
    if (state >= res) {
        return;
    }
    if (x == gx && y == gy) {
        res = min(res, state);
        return;
    }
    
    int now;
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (i < 2) now = -1;
        else now = 1;
        if (nx >= 0 && nx < n && ny >= 0 && ny < n && vis[nx][ny] == 0 && ma[nx][ny] != 'x') {
            vis[nx][ny] = 1;
            if (pre * now == -1) {
                dfs(nx, ny, state + 1, now);
            } else {
                dfs(nx, ny, state, now);
            }
            vis[nx][ny] = 0;
        }
    }
}

int main(void)
{
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> ma[i][j];
            if (ma[i][j] == 'A') {
                sx = i, sy = j;
            } 
            else if (ma[i][j] == 'B'){
                gx = i, gy = j;
            }
        }
    }
    vis[sx][sy] = 1;
    dfs(sx, sy, 0, 0);
    cout << (res == INF ? -1 : res) << endl;
    
    return 0;
}

B - 牛牛的零食

题解:https://www.cnblogs.com/LinqiongTaoist/p/7203723.html

神奇的容斥原理,注意此时给出的数不是素数,所以计算重合的部分时,不能直接相乘,需要计算最小公倍数

#include 
using namespace std;
typedef long long ll;
const int N = 20;

ll n, a, b, ans;
ll num[N];
// 最大公因数
ll gcd(ll a, ll b)
{
    if (b == 0) return a;
    return gcd(b, a % b);
}
// 最小公倍数
ll lcm(ll a, ll b)
{
    return a * b / gcd(a, b);
}

void dfs(ll u, ll state, ll cnt)
{
	// 安排了n个数
    if (u == n) {
        if (cnt % 2 == 0) {
            ans += b/state - a/state;
        } else {
            ans -= b/state - a/state; 
        }
        return;
    }
    // 剪枝
    if (state > b) {
        return;
    }
    // 选当前数
    dfs(u + 1, lcm(state, num[u]), cnt + 1); 
    // 不选当前数
    dfs(u + 1, state, cnt);
}

int main(void)
{
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> num[i];
    cin >> a >> b;
    a--; 
    dfs(0, 8, 0); 
    
    cout << ans << endl;

	return 0;
}

E - 只能吃土豆的牛牛

类似于64位乘法,送温暖题

#include 
#include 
using namespace std;
typedef long long ll;

ll pow(ll k)
{
    ll res = 0, x = 1;
    while (k > 0) {
        if (k & 1) res += x;
        x *= 3;
        k >>= 1;
    }
    return res;
}

int main(void)
{
    int t, k, idx = 1;
    cin >> t;
    while (t--) {
        cin >> k;
        printf("Case #%d: %lld\n", idx++, pow(k)); 
    }
    
    return 0;
}

你可能感兴趣的:(#,一些比赛题目)