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;
}

 

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