【随机化】

【随机化】

能在若干次内随机试出且大概率正确

常用函数

rand 生成随机整数

使用时需要#include<cstdlib>
可用取模来规定大小
需要生成随机种子:srand(time(nullptr))

预定义随机数生成器

mt19937

类似于rand()
使用时用其定义一个随机数生成器:std::mt19937 myrand(seed)
seed 可不填,不填 seed 则会使用默认随机种子

#include<bits/stdc++.h>
using namespace std;

int main() {
  mt19937 myrand(time(nullptr));
  cout << myrand() << endl;
  return 0;
}

minstd_rand0 线性同余生成器

$s_i \equiv s_{i-1} \times A + C $

#include<bits/stdc++.h>
using namespace std;

int main() {
    minstd_rand0 rng;
    rng.seed(chrono::steady_clock::now().time_since_epoch().count());
	//rng():原始随机数
    uniform_int_distribution<int> dist(1, 100);//范围随机数
    return 0;
}

random_shuffle 随机打乱容器中元素的顺序

使用时需要#include<algorithm>

#include<bits/stdc++.h>
using namespace std;
int main() {
    vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    srand(time(0));
    random_shuffle(nums.begin(), nums.end());
    // 示例输出(每次不同):5 1 9 3 7 2 8 4 6
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
int my_rand(int n) {
    return rand() % n;  // 基于 rand() 实现
}
int main() {
    vector<char> chars = {'a', 'b', 'c', 'd', 'e'};
    srand(time(0));
    random_shuffle(chars.begin(), chars.end(), my_rand);
    for (char c : chars) {
        cout << c << " ";
    }
    // 示例输出:c e a b d
    return 0;
}

例题整理

Colinear

证明随机可行+计算几何(直线一般式)

https://atcoder.jp/contests/abc422/tasks/abc422_e

题目大意

8986e55a-4c92-48ad-bc48-12138376d889

思路

26de09f9-4355-4001-ac4b-5a1fca5913b9

代码

int n;
vector<i64> lineGeneralForm(i64 x1, i64 y1, i64 x2, i64 y2) {
    // 处理两点重合的情况
    if (x1 == x2 && y1 == y2) {
        return {0, 0, 0}; // 两点重合,无法确定一条直线
    }
    
    // 计算A、B、C的初始值:已知两点求一般式
    i64 A = y2 - y1;
    i64 B = x1 - x2;
    i64 C = x2 * y1 - x1 * y2;
    
    // 计算最大公约数,用于化简
    i64 g = gcd(llabs(A), gcd(llabs(B), llabs(C)));
    if (g != 0) {
        A /= g;
        B /= g;
        C /= g;
    }
    
    // 确保首项系数为正(约定)
    if (A < 0 || (A == 0 && B < 0)) {
        A = -A;
        B = -B;
        C = -C;
    }
    
    return {A, B, C};
}
void solve(){
    cin>>n;
    vector<P64> a(n+1);
    for(int i=1;i<=n;i++) cin>>a[i].fi>>a[i].sc;
    int cnt=100;
    for(int i=1;i<=cnt;i++){
        i64 p=rand()%n+1,q=rand()%n+1;
        if(p==q) continue;
        vector<i64> line=lineGeneralForm(a[p].fi,a[p].sc,a[q].fi,a[q].sc);
        int cn=2;
        for(int j=1;j<=n;j++){
            if(j==p || j==q) continue;
            if((line[0]*a[j].fi+line[1]*a[j].sc+line[2])==0){
                cn++;
            }
        }
        if(cn>n/2){
            cout<<"Yes"<<endl;
            for(auto son:line){
                cout<<son<<" ";
            }
            cout<<endl;
            return;
        }
    }
    cout<<"No"<<endl;
}
posted @ 2025-09-19 16:23  White_ink  阅读(5)  评论(0)    收藏  举报