2020杭电多校(7)

1010. Jogging

Jogging

题意

给定一个坐标((x, y)),可以向八个方向(八连通)和停在原地(概率为(frac{1}{z+1})),z为可达点(包括本身)的大小

限制为可达点的(gcd(x, y) !=1)

求当步数无限时,停留在原点的概率

思路

观察下图发现,当到达x == y 时,概率为0

然后根据样例推测,可以从可达区域的每个点出发,走一步的情况之和为分母,走到原点的情况为分子

用gcd约分即可

所以可以通过搜索,这里我用的BFS,如果到达x == y 的点则0,

否则按上述计算概率

可行性分析,观察图片可发现,每个块都会由4个素数所分割,可放心搜索

image-20200811185436127

代码

/*************************************************************************
 > FileName:
 > Author:      Lance
 > Mail:        lancelot_hcs@qq.com
 > Date:        9102.1.8
 > Description:
 ************************************************************************/
//#include <bits/stdc++.h>
//#pragma comment(linker, "/STACK:102400000,102400000")//add_stack
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <vector>
#include <cstdio>
#include <bitset>
#include <string>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PII;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int mod = 1e9 + 7;
#define debug(a) cout << "*" << a << "*" << endl
const int INF = 0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
const int maxn = 1000005;
//sacnf("%lf") printf("%f")
ll read()
{
    ll x = 0,f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
        f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
ll t, n, x, y;
int dir[8][2] = {1, 0, 0, 1, 1, 1, -1, -1, 0, -1, -1, 0, -1, 1, 1, -1};
map<PII, ll> MX;

inline bool test(ll x, ll y) {return  __gcd(x, y) != 1 && (!(MX[{x, y}]));}
vector<PII> A;
ll ans = 0, con = 0;
bool bfs(ll x, ll y) {
    queue<PII> Q;
    Q.push({x, y});
    A.push_back({x, y});
    MX[{x,y}] = 1;
    while (!Q.empty()) {
        PII top = Q.front();
        Q.pop();
        if (top.first == top.second) return 1;
        for (int i = 0; i < 8; i++) {
            ll xx = top.first + dir[i][0], yy = top.second + dir[i][1];
            if (test(xx, yy)) {
                MX[{xx, yy}] = 1;
                Q.push({xx, yy});
                A.push_back({xx, yy});
                ans++;
                if (top.first == x && top.second == y) {
                    con++;
                }
            }
        }
    }
    return 0;
} 
ll count(ll x, ll y) {
    ll res = 0;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            if (__gcd(x + i, y + j) != 1) {
                res++;
            }
        }
    }
    return res;
}
void solve()
{
    t = read();
    while (t--) {
        ans = 1;
        con = 1;
        MX.clear();
        A.clear();
        x = read(), y = read();
        if (bfs(x, y)) {
            puts("0/1");continue;
        }
        ll di = 0;
        for (int i = 0; i < A.size(); i++) {
            PII it = A[i];
            di += count(it.first, it.second);
        }
        con = count(x, y);
        ll gc = __gcd(con, di);
        printf("%lld/%lld
", con / gc, di / gc);
    }
}

int main()
{

//    freopen("F:/Overflow/in.txt","r",stdin);
//    ios::sync_with_stdio(false);
    solve();
    return 0;
}

image-20200811185819119

1009. Increasing and Decreasing

Increasing and Decreasing

题意

思路

1

代码


原文地址:https://www.cnblogs.com/lanclot-/p/13479494.html