一、问题描述
二、问题分析
直观的求解方法就是暴力模拟,进一步进行简化可以发现数字的编号对于求解关系不大,那么就可以用另一种编号模拟,再进一步简化可以发现当不考虑中间5的时候,其他的编号的地位是等价的,那么可以只算其中一种方式的解(比如除5外,第一次击中的必有1),再乘以8,同样可以得出结果。如下代码实现均使用第二种模拟方法。
三、代码实现
1.C/C++实现
#include <iostream>
using namespace std;
int get_counts(int* nums, int len, int res)
{
// 对于问题来说编号改变无关解题
// 这里用0-7代表1,2,3,4,6,7,8,9;用8代表5方便解题
if (res == 0)
return 1;
int result = 0;
// 单独判断 5
if (!nums[len - 1])
{
nums[len - 1] = 1;
result += get_counts(nums, len, res - 1);
nums[len - 1] = 0;
}
for (int i = 0; i < len - 1; i++)
{
if (!nums[i])
{
nums[i] = 1;
// 此次打掉 1 个
result += get_counts(nums, len, res - 1);
int t = (i + 1) % (len - 1);
if (!nums[t])
{
nums[t] = 1;
// 此次打掉 2 个
result += get_counts(nums, len, res - 2);
nums[t] = 0;
}
nums[i] = 0;
}
}
return result;
}
int main()
{
int a[10];
memset(a, 0, sizeof(a));
cout << get_counts(a, 9, 9) << endl;
return 0;
}
2.Python实现
# coding=utf-8
def get_counts(nums, flag):
if nums.count(0) == 0:
return 1
count = 0
if flag:
count += get_counts(nums, False)
for i in range(len(nums)):
if nums[i] == 0:
nums[i] = 1
count += get_counts(nums, flag)
t = (i + 1) % len(nums)
if nums[t] == 0:
nums[t] = 1
count += get_counts(nums, flag)
nums[t] = 0
nums[i] = 0
return count
if __name__ == '__main__':
print(get_counts([0] * 8, True))
pass