ACM 随机化

参考文档:

https://blog.csdn.net/caimouse/article/details/55668071 (mt19937随机数)

https://blog.csdn.net/sr_19930829/article/details/38236769 (POJ 3318)

 

随机化算法即随机生成因子,利用其随机生成数结合题目条件对所给数据进行校验。

需要保证前提:

1.有明确的正确数据以供校验

2.随机化的次数必须要足够多以保证所有数据得到验证以保障准确性

 

例题

1.Matrix Multiplication(POJ 3318)

http://poj.org/problem?id=3318

 

题目大意:给定三个矩阵问其中C矩阵是否是给定的A和B矩阵相乘得到的矩阵。

题目本身给了hint:O(N^3)会TLE

因此该题可以使用随机化方法验证给定数据以判断是否正确。

AC代码如下:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <set>
#include <queue>
#include <iomanip>
#include <time.h>
using namespace std;
typedef long long ll;
const int maxn = 500 + 5;
int a[maxn][maxn];
int b[maxn][maxn];
int c[maxn][maxn];
int main(){
    int n;
    while(scanf("%d",&n)!=EOF) {
        srand(time(NULL));                    //随机化种子
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        memset(c, 0, sizeof(c));

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                scanf("%d", &a[i][j]);
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                scanf("%d", &b[i][j]);
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                scanf("%d", &c[i][j]);
            }
        }

        bool f = 1;
        for (int k = 1; k <= 30000; k++) {
            int row = rand() % n + 1;        //从1开始生成行
            int col = rand() % n + 1;        //从1开始生成列
            int tmp = 0;
            for (int i = 1; i <= n; i++)
                tmp += (a[row][i] * b[i][col]);
            if (tmp != c[row][col])          // 不符合要求
                f = 0;


        }
        if (f) printf("YES\n");
        else printf("NO\n");

    }
    return 0;
}

 

2.Hamming Distance(HDU 4712)

 

题目大意:两个二进制字符串之间任意两个值抑或值中的1的个数。

由题意可知该值只能在0~20,因此采取随机化探测。

读入字符串后任意选取(随机)的编号,(不能重复),进行计算并且每次取最小值。

 

AC代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <time.h>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 5;
int cal(int x) {                //计算1的个数
    int ans = 0;
    while(x) {
        ans += (x&1);
        x>>=1;
    }
    return ans;
}
int num[maxn];

int main(){
    int t;
    scanf("%d",&t) ;
        while(t--) {
        srand(time(NULL));     //随机化种子
        int tmp = 25;          //保证足够大
        int n;
        scanf("%d",&n);
        for(int i = 1; i <= n; i++) scanf("%X",&num[i]);    //%X即十六进制数
        for(int i = 0; i < 200000; i++) {                   //保证足够多
            int j = rand() % n + 1;
            int k = rand() % n + 1;
            if (j == k) j = j % n + 1;                      //如果相等需要处理
            tmp = min(tmp, cal(num[j] ^ num[k]));           //进行计算
        }
        printf("%d\n",tmp);

    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章