版权声明:本文为博主原创文章,欢迎转载,转载请声明出处! https://blog.csdn.net/hansionz/article/details/82694214
题目:从扑克牌中随机抽取5张牌,判断是不是一个顺子
,既这5张牌是不是连续的。2-10位数字本身
,A为1,J为11,Q为12,K为13
,大王和小王可以看出是任何数
。
解决思路:
- 1.把大王和小王看做是0
- 2.对所给序列进行排序
- 3.统计差值的个数(如果相邻的两个值差1,则差值为0,如果差大于1,则插入为n-1)
- 4.统计0的个数
- 5.比较。如果差值的个数大于0,则必然不是顺子,否则是顺子
代码实现:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//直接插入排序
int InsertSort(int *num, int len)
{
assert(num);
int i = 0;
//第一个元素已经为有序序列,所以要进行len-1次排序
for (; i < len - 1; i++)
{
int end = i;
int tmp = num[i + 1];//保存非有序区间第一个元素,否则在后边的移动中会改变
//比较后移
while (end >= 0 && num[end]>tmp)
{
num[end + 1] = num[end];
--end;
}
//插入到适当位置
num[end + 1] = tmp;
}
}
int Compare(const void* arg1, const void* arg2)
{
return *(int*)arg1 - *(int*)arg2;
}
//判断是否为一个顺子(是返回1,不是返回0)
int CheckContiuos(int *num, int len)
{
assert(num);
if (len <= 0)
return 0;
//1.排序
/*InsertSort(num, len);*/
//直接调用库函数qsort(时间复杂度为O(nlogn))
qsort(num, len, sizeof(int), Compare);
//0代表大小王,可以随意替换
int number_zero = 0;//记录0的个数
//2.统计0的个数
for (int i = 0; i < len; i++)
{
if (num[i] == 0)
++number_zero;
}
//3.统计差值的个数
int number_gap = 0;//记录差值的个数
int low = number_zero;//非0第一个值的下标
int high = low + 1;//low后边那个值得下标,为了计算差值
while (high < len)
{
//如果存在对子,绝对不是对子
if (num[low] == num[high])
return 0;
//每个相邻的数间隔1是正常的,多出来的就算差值
number_gap += num[high] - num[low] - 1;
low++;//继续向后查找
high++;
}
//差值的个数如果比0的个数多,则肯定不是顺子
return (number_gap > number_zero) ? 0 : 1;
}
int main()
{
int num[] = { 1, 2, 3, 6, 6, 0, 0 };
int len = sizeof(num) / sizeof(num[0]);
int ret = CheckContiuos(num, len);
printf("%d\n", ret);
return 0;
}
注意:排序可以采用不同的做法,如果要效率高的话,也可以考虑用哈希表做,上边的代码是用的是插入排序和直接调用库函数qsort。