2020杭电多校(7)

1010. Jogging

Jogging

题意

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

限制为可达点的 g c d ( x , y ) ! = 1 gcd(x, y) !=1 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\n", 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

代码


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值