描述
给定一个不重复的数组,找出所有的三元组,其中三元组之积等于一个给定的整数。
找出符合上述条件所有的三元组个数Input:
3
10 6
3 1 0 4 2 5 6 8 7 9
8 12
1 4 6 2 3 8 16 18
3 122
122 1 4
Output:
1
2
0
说明:
对于上例来说:有10个互不重复的数组,给定的数为6,所以符合条件的三元组为[1,2,3],[1,3,2]、[3,1,2],但这三个其实都是一个,故输出为1. 第二个例子为8个互不重复的数组,给定数为12,故符合条件的三元组为[1,3,4]、[1,2,6],所以结果输出为2. ,以此类推。
issue
组合算法用回溯法。递归算法会增大算法时间开销
#include<stdio.h>
#include<stdlib.h>
#define MAXLEN 1024
#define MAX 1024
int a1[MAX];
int cmp(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
//Cm n 组合算法
int comb(int n, int r)
{
int i, j,count = 0;
i = 0;
a1[i] = 1;
do {
if (a1[i] - i <= n - r + 1)
{
if (i == r - 1)
{
count++;
/*for (j = 0; j < r; j++) //可用作测试
printf("%4d", a[j]);
printf("\n");*/
a1[i]++;
continue;
}
i++;
a1[i] = a1[i - 1] + 1;
}
else
{
if (i == 0)
return count;
a1[--i]++;
}
} while (1);
}
int solution(int nums[],int size , int item)
{
int result = 0;
//先排序
qsort(nums, size, sizeof(int), cmp);
if (item == 0 && nums[0] != 0)
{
return 0;
}
if (item == 0 && nums[0] == 0)//0的情况用组合算法计算
{
return comb(size - 1, 2);
}
//用三个指针,逐一搜索符合条件的结果数量
for (int i = 0; i < size; i++) {
int L = i + 1;
int R = size - 1;
while (L < R) {
int multi = nums[i] * nums[L] * nums[R];//三数之积
if (multi == item) {
//printf("%d , %d , %d\n", nums[i], nums[L], nums[R]);
result++;
L++;
R--;
}
else if (multi < item) L++;//移动左指针
else if (multi > item) R--;//移动右指针
}
}
return result;
}
int main()
{
int a[MAXLEN];
int T, n, item, i = 0 , count = 0;
scanf_s("%d", &T);
int result[MAXLEN] = {0};
int num = T;
while ( T != 0 )
{
scanf_s("%d%d", &n, &item);
for (count = 0; count < n; count++)
{
scanf_s("%d", &a[count]);
}
result[i] = solution(a,n,item);
++i;
--T;
}
for (int j = 0; j < num; ++j)
{
printf("%d\n", result[j]);
}
}