他们决定依次由甲,乙,丙,丁,卯五个海盗来分当由甲分时,
剩下的海盗表决,
如果乙,丙,丁,卯四人中有一半以及以上反对就把甲扔下海,
再由乙分……以此类推;如果超过一半的人同意,就按甲的分法。
请问甲要依次分给乙,丙,丁,卯多少才能不被扔下海并且让
自己拿到最多?
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<memory.h>
void fun(int n, int m, int q);
void display(int *a, int n);
void sort(int *a, int n, int zc, int m);//从小到大排序,不交换数据
int main1233()
{
int i = 1;
//根据前面的分析,n个海盗的情况依赖于n-1海盗的情况。因此需要循环从小到大。
//fun函数就将海盗为i的情况计算了出来。
for (i = 0; i <= 5; i++)
{
fun(i, 100, 50);
}
system("pause");
return 0;
}
//打印当前每一个海盗能够分到的金币数,-1代表要被抛下。
void display(int *a, int n)
{
int i;
for (i = 0; i<n - 1; i++)
{
printf("%d, ", a[i]);
}
printf("%d\n", a[i]);
}
//从小到大排序,不交换数据
void sort(int *a, int n, int zc, int m)
{
int *point = NULL;
int i, j, k, l = 0, sum = 0, temp;
n--;
if (zc >= n) //代表该喊道不能得到大多数支持。一定会被跑下去,所以赋值为-1.
{
a[n] = -1;
return;
}
point = (int*)malloc(sizeof(int)*n);
for (i = 0; i<n; i++)//对角标初始化
{
point[i] = i;
}
//选择排序,从小到大排序
for (i = 0; i<n - 1; i++)
{
k = i;
for (j = i + 1; j<n; j++)
{
if (a[point[k]]>a[point[j]])
{
k = j;
}
}
if (k != i)
{
temp = point[i];
point[i] = point[k];
point[k] = temp;
}
}//end for
//开始贿赂zc个人
for (i = 0; i<zc; i++)
{
if (a[point[i]] == -1)
{
a[point[i]] = 0;
continue;
}
a[point[i]]++;
sum += a[point[i]];//统计花费的金币
}
for (; i<n; i++) //其他人的支持不用了。
{
a[point[i]] = 0;
}
//表示第n个人必死,因为金币不够分
if (m>sum)
{
a[n] = m - sum;
}
else
{
a[n] = -1;
}
free(point);//释放内存
}
//n:海盗数
//m:金币数
//q:支持人数比例
void fun(int n, int m, int q)
{
int i, zc, *person;//zc表示支持的人数
//过滤参数不合法的情况,q的合法值为
if (n <= 0 || m <= 0 || q<0 || q>100)
{
return;
}
if (n == 1) //只剩下一个人。独吞。
{
printf("%d\n", m);
return;
}
//如果需要支持率100,除最后一个外,其余都得挂掉
if (q == 100)
{
for (i = 0; i<n - 1; i++)
{
printf("-1 , ");
}
printf("%d", m);
return;
}
person = (int*)malloc(sizeof(int)*n);//n个人
person[0] = m;
for (i = 2; i <= n; i++)
{
zc = i * q / 100;//zc的值表示除了出方案的人支持外还另外需要支持的人数
sort(person, i, zc, m);
}
display(person, n);//打印结果
free(person);//释放内存
}