说说在训练赛中的问题

目录

一、新生赛C题介绍

二、自己写的代码及问题

三、正确代码及错误总结


        一、新生赛C题介绍

C题是codeforce上的1651A题       

考虑一个淘汰赛锦标赛,有2n2n名运动员参加。这些运动员的编号从11到2n2n。

比赛分为nn个阶段。在每个阶段,运动员被分成一对,使得每个运动员恰好属于一对。在每一对中,运动员互相竞争,只有一名获胜者。每对中的获胜者进入下一阶段,被击败的运动员被淘汰出比赛。

对阵方式如下:

  • 第一阶段,运动员11对阵22;33对阵44;55对阵66,依此类推;
  • 第二阶段,比赛"11–22"的获胜者对阵比赛"33–44"的获胜者;比赛"55–66"的获胜者对阵比赛"77–88"的获胜者,依此类推;
  • 后续阶段按照相同规则进行。

当运动员xx和yy比赛时,获胜者的决定如下:

  • 如果x+yx+y是奇数,则编号较低的运动员获胜(即如果x<yx<y,则xx获胜,否则yy获胜);
  • 如果x+yx+y是偶数,则编号较高的运动员获胜。

下图描述了有n=3n=3名运动员参加的比赛方式。

你的任务是:给定整数nn,确定赢得比赛的运动员的编号。

输入

第一行包含一个整数tt(1≤t≤301≤t≤30)— 测试用例的数量。

每个测试用例包含一行,包含一个整数nn(1≤n≤301≤n≤30)。

输出

对于每个测试用例,输出一个整数 — 赢得比赛的运动员的编号。

示例 1

InputcopyOutputcopy
2
3
1
7
1

注意

案例n=3n=3在题目的图片中有展示。

如果n=1n=1,那么11和22之间只有一场比赛。由于1+2=31+2=3是奇数,编号较低的运动员获胜。所以,运动员11获胜。

二、自己写的代码和出现的问题

我在写这个题目的时候想用函数的调用,递归的方式;但是遇到了整形提升的问题。在本题中由于我使用的是int类型,导致数据溢出,部分数据丢失。

#include <stdio.h>

int findWinner(int n) {
    if (n == 1) {
        return 1;
    } else {
        if (n % 2 == 0) { // 如果 n 是偶数
            return 2 * findWinner(n / 2);
        } else { // 如果 n 是奇数
            return 2 * findWinner(n / 2) - 1;
        }
    }
}

int main() {
    int t;
    scanf("%d", &t);

    while (t--) {
        int n;
        scanf("%d", &n);
        printf("%d\n", findWinner(1 << n));
    }

    return 0;
}

关于整形提升,有关其的概念如下:

C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符(char)和短整型(short)操作数在使用之前被转换为普通整型,这种转换称为整型提升

需要用到的原因是:

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长一般就是    int  的字节长度,同时也是CPU的通用寄存器的长度。
因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长
度(int)。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值(char 和 short),都必须先车换为 int 或  unsigned int,然后才能送入CPU去执行运算。

有关整形提升的规则:

1.对于有符号数(char, signed char ,short, signed short)整形提升转化成标准长度(int)时,在左端补得是最高位(符号位),正数补0,负数补1

2.对于无符号数(unsigned short ,unsigned char),在左端补得就是0

注意:

1.整形存放在内存中的是补码(所以运算是针对补码的)

2. 打印时的数值 是打印原码对应的10进制数值

3.用%d打印char类型的数据,因为不够4个字节,要发生整形提升

4. %u 是打印无符号数,如果是有符号数,也按照无符号数来打印

5.%d 是打印有符号数,如果是无符号数,也按照有符号数来打印

6.定义变量时,类型标识符决定了整形提升时 是遵循有符号数整形提升规则,还是无符号数整形提升规则(但是和打印值时认为是无符号数,还是有符号数没有关系,这个取决于%d或%u)

三、正确代码及错误总结

在将int类型换成长整型long之后,由于字节长度的增加,储存空间也增加了,使得内存不足的问题得到解决,数据也不会丢失了;从而成功AC

正确代码示例:

#include <stdio.h>
int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        long long n;
        scanf("%llu", &n);
        printf("%llu\n",(1 << n)-1);
    }
    return 0;
}

总结:我将重新复习有关类型转换与整型提升问题,重新听鹏哥课程表达式课;纠正以上错误并继续进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值