c语言计算跳水分数,C语言判断五位选手跳水名次

有这样一个问题:5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果

A选手说:B第二,我第三;

B选手说:我第二,E第四;

C选手说:我第一,D第二;

D选手说:C最后,我第三;

E选手说:我第四,A第一;

比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

那我们就有了这样一个思路:假设第一位选手名次开始为一,在这位选手为一的情况下假设第二个人为一(名次可以并列),依次假设下去,即五个循环嵌套,最后使用题目条件判断,满足条件的输出结果,代码如下:

#define _CRT_SECURE_NO_WARNINGS 1

#include

#include

int main() {

int a = 1;

int b = 1;

int c = 1;

int d = 1;

int e = 1;

for (; a <= 5; a++){

for (b = 1; b <= 5; b++){

for (c = 1; c <= 5; c++){

for (d = 1; d <= 5; d++){

for (e = 1; e <= 5; e++){

if (((a == 3) + (b == 2)) == 1 && \

((b == 2) + (e == 4)) == 1 && \

((c == 1) + (d == 2)) == 1 && \

((c == 5) + (d == 3)) == 1 && \

((e == 4) + (a == 1)) == 1)

{

printf("final result: a=%d,b=%d,c=%d,d=%d,e=%d\n", \

a, b, c, d, e);

}

}

}

}

}

}

system("pause");

return 0;

}

打印结果如下:

134835a2e6d1fcfae7338938afff2ebd.png

得到的结果是不是大吃一惊,怎么有的结果竟然没有第一名,开始我们思路很好,代码整体也没问题,但我们忽略了这个细节,我们没有排除不正常的名次,正常的名次肯定中间的名次是不能断(简称名次断节),可以并列,甚至可以都是第一名,那么我们就可以用一种十分巧妙的方法来排除这种名次断节的情况,接下来的讲解略有难度,小伙伴认真听。

定义一个整形,使用整形的最低的五个比特位来存五位选手的名次,从右到左比特位为第一名到第五名,比特位上有1就说明对应的那一位有名次, 比如后五位为00101,有第一名,有第三名,没第二名,这显然是不正确的,,就是1之间不能夹着0,比如00011,只有第一名和第二名,名次存在并列,这显然可以,我们只需在原先条件后加点筛选条件就好了,

判断条件如下:

if (((a == 3) + (b == 2)) == 1 && \

((b == 2) + (e == 4)) == 1 && \

((c == 1) + (d == 2)) == 1 && \

((c == 5) + (d == 3)) == 1 && \

((e == 4) + (a == 1)) == 1)

{

int flag = 0;//他的后五位比特位存名次

flag = flag|(1 << (a - 1));

flag = flag|(1 << (b - 1));

flag = flag|(1 << (c - 1));

flag = flag|(1 << (d - 1));

flag = flag|(1 << (e - 1));

while (flag)//比特位存在1,跳出这个循环有两种情况,\

一种是1之间夹着0,一种是比特位全部向右移动完遇到0退出循环

{

if (!(flag & 1))//排除是110等最低位为0的情况,

{

break;

}

flag >>= 1;//最低位不是0就向后移一位再检查最低位是不是0

}

if (flag == 0)//满足flag==0说明比特位正常移动完毕,比如00111,

这是个可以的结果,flag>>1执行三次之后最低位遇到0,跳出 \

while(flag)的循环,到了这里后flag为00000,flag==0,满足条件,\

输出正确结果

{

printf("final result: a=%d,b=%d,c=%d,d=%d,e=%d\n", \

a, b, c, d, e);

}

}

int flag = 0;//这段代码的作用是每次得到一个满足原始\

条件的a b c d e的数字时用1移位,比如得到a=1,b=2,c=1,d=2,e=3,

flag = flag|(1 << (a - 1));//flag二进制为00001

flag = flag|(1 << (b - 1));//flag二进制为00011

flag = flag|(1 << (c - 1));//flag二进制为00011

flag = flag|(1 << (d - 1));//flag二进制为00011

flag = flag|(1 << (e - 1));//flag二进制为00111//这个00111结果是满足条件的,所以最后输出abcde相应的值

完整代码:

#define _CRT_SECURE_NO_WARNINGS 1

#include

#include

int main() {

int a = 1;

int b = 1;

int c = 1;

int d = 1;

int e = 1;

for (; a <= 5; a++){

for (b = 1; b <= 5; b++){

for (c = 1; c <= 5; c++){

for (d = 1; d <= 5; d++){

for (e = 1; e <= 5; e++){

if (((a == 3) + (b == 2)) == 1 && \

((b == 2) + (e == 4)) == 1 && \

((c == 1) + (d == 2)) == 1 && \

((c == 5) + (d == 3)) == 1 && \

((e == 4) + (a == 1)) == 1)

{

int flag = 0;

flag = flag|(1 << (a - 1));

flag = flag|(1 << (b - 1));

flag = flag|(1 << (c - 1));

flag = flag|(1 << (d - 1));

flag = flag|(1 << (e - 1));

while (flag)//比特位存在1,跳出这个循环有两种情况,\

一种是1之间夹着0,一种是比特位全部向右移动完遇到0退出循环

{

if (!(flag & 1))//

{

break;//排除是110等最低位为0的情况,

}

flag >>= 1;//最低位不是0就向后移一位再检查最低位是不是0

}

if (flag == 0)//满足flag==0说明比特位正常移动完毕,比如00111,\

这是个可以的结果,flag>>1执行三次之后最低位遇到0,跳出 \

while(flag)的循环,到了这里后flag为00000,flag==0,满足条件,\

输出正确结果

{

printf("final result: a=%d,b=%d,c=%d,d=%d,e=%d\n", \

a, b, c, d, e);

}

}

}

}

}

}

}

system("pause");

return 0;

}

正确结果:

99087edac10424f54c7175486f381a93.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值