參考文檔:
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;
}