2020杭电多校(7)

概率与搜索算法在数论问题中的应用
该篇博客探讨了一道概率与搜索算法相结合的数学问题,具体涉及在给定坐标上,根据特定移动规则求解停留在原点的概率。通过分析,博主提出从可达区域的每个点出发,计算每一步的可达状态,利用gcd(x,y)来排除无效状态,并采用BFS搜索策略。最终,博主给出了代码实现,展示了如何计算并简化概率表达式。

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

代码


### 杭电比赛与童年经历 杭电比赛作为国内知名的 ACM/ICPC 训练平台之一,吸引了大量热爱算法的学生参与其中。对于许参赛者来说,这些比赛不仅是技术上的挑战,更是一段难忘的成长历程。 从早期的竞赛启蒙来看,很选手最初接触编程和算法完全是因为兴趣使然[^1]。例如,在高中阶段参加 OI 或类似的训练活动时,许人并未意识到其重要性,仅仅将其视为一种娱乐方式。这种轻松的心态反而可能带来意想不到的好成绩,比如某次模拟赛中因团队合作默契而意外夺冠的经历。 当提到杭电比赛的具体题目或经历时,这类赛事通常会设计一系列覆盖广泛知识点的问题来考验参赛者的综合能力。以下是几个典型的例子: #### 题目示例 1. **基础数据结构应用** 这类题目往往考察数组、链表等基本概念的应用场景。 ```cpp // 示例代码:简单的数组遍历求最大值 int findMax(int arr[], int n) { int maxVal = arr[0]; for (int i = 1; i < n; ++i) { if (arr[i] > maxVal) { maxVal = arr[i]; } } return maxVal; } ``` 2. **动态规划入门** 动态规划是 ACM 中非常重要的技巧之一,初学者可以通过经典的背包问题熟悉该方法。 ```python # 背包问题实现 def knapsack(W, wt, val, n): dp = [[0 for _ in range(W + 1)] for __ in range(n + 1)] for i in range(1, n + 1): for w in range(1, W + 1): if wt[i-1] <= w: dp[i][w] = max(dp[i-1][w], dp[i-1][w-wt[i-1]] + val[i-1]) else: dp[i][w] = dp[i-1][w] return dp[n][W] ``` 3. **图论初步探索** 图论相关题目常涉及最短路径计算或者连通性分析等内容。 ```java import java.util.*; public class ShortestPath { static final int INF = Integer.MAX_VALUE / 2; public static void dijkstra(List<List<int[]>> adjList, int start, int[] dist){ PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1])); Arrays.fill(dist, INF); dist[start] = 0; pq.add(new int[]{start, 0}); while(!pq.isEmpty()){ int[] current = pq.poll(); int u = current[0]; if(current[1] > dist[u]) continue; for(int[] edge : adjList.get(u)){ int v = edge[0], weight = edge[1]; if(dist[v] > dist[u] + weight){ dist[v] = dist[u] + weight; pq.add(new int[]{v, dist[v]}); } } } } } ``` 通过上述实例可以看出,无论是童年的简单尝试还是后来深入学习后的复杂解法,每一次练习都为未来打下了坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值