海盗分金,追梦出手,必属精品

有一天,有5个很精明的海盗抢到100个金币,
他们决定依次由甲,乙,丙,丁,卯五个海盗来分当由甲分时,
剩下的海盗表决,
如果乙,丙,丁,卯四人中有一半以及以上反对就把甲扔下海,
再由乙分……以此类推;如果超过一半的人同意,就按甲的分法。
请问甲要依次分给乙,丙,丁,卯多少才能不被扔下海并且让

自己拿到最多?


#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);//释放内存
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值