本帖最后由 guosl 于 2021-3-21 12:56 编辑
这题也可以通过组合数学中的母函数展开来做。只是时间比较长。但可以用GPU来编程计算。在GTX1060上2秒多点可以得出结果。/*
用母函数展开来做
答案:55374
耗时:2.07287秒(GTX1060显卡)
*/
#include <iostream>
#include <algorithm>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <helper_cuda.h>
using namespace std;
const int N = 64000;
const int nBlocksSize = 256;
int *a, *b, c[N];
bool *bFind;
__global__ void Polynomial_Mul(int *p1, int *p2, int k, bool *bFlag)
{
int i = blockIdx.x * nBlocksSize + threadIdx.x;
if (i >= N)
return;
p2[i] = 0;
for (int j = 0; j <= i; j += k)
{
p2[i] += p1[i - j];
p2[i] %= 1000000;
}
if (i == k)
{
if (p2[k] == 0)
*bFlag = true;
}
}
void find_zero(int *p1, int *p2, int k)
{
Polynomial_Mul <<<N / nBlocksSize, nBlocksSize >>> (p1, p2, k, bFind);
}
int main(void)
{
cudaDeviceProp deviceProp;
int devID = gpuGetMaxGflopsDeviceId();
cudaSetDevice(devID);//设置计算卡
cudaGetDeviceProperties(&deviceProp, devID);
printf("GPU Device %d: "%s" with compute capability %d.%d\n\n",
devID, deviceProp.name, deviceProp.major, deviceProp.minor);
//在显卡上分配内存
cudaMalloc((void**)&a, N * sizeof(int));
cudaMalloc((void**)&b, N * sizeof(int));
cudaMalloc((void**)&bFind, sizeof(int));
//设置计算的初始向量
for (int i = 0; i < N; ++i)
c[i] = 1;
cudaMemcpy(a, c, N * sizeof(int), cudaMemcpyHostToDevice);
int *p1 = a, *p2 = b;
for (int k = 2; k < N; ++k) //开始逐个展开母函数
{
bool bFlag = false;//设置返回值的初值
cudaMemcpy(bFind, &bFlag, sizeof(bool), cudaMemcpyHostToDevice);
find_zero(p1, p2, k);//计算第k次展开
swap(p1, p2);
cudaGetLastError();
cudaDeviceSynchronize();//等待计算完成
cudaMemcpy(&bFlag, bFind, sizeof(bool), cudaMemcpyDeviceToHost);//获取本次计算的结果
if (bFlag)//找到结果
{
cout << k << endl;
break;
}
}
cudaFree(a);
cudaFree(b);
cudaFree(bFind);
return 0;
}
|