信息学奥赛复赛复习15-CSP-J2022-01乘方-数据类型、类型转换、数据类型溢出、指数、模拟指数运算
PDF文档公众号回复关键字:20241009
1 P8813 [CSP-J 2022] 乘方
[题目描述]
小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数 a 和 b,求 a^b 的值是多少。
a^b 即 b 个 a 相乘的值,例如 2^3 即为 3 个 2 相乘,结果为 2×2×2=8
“简单!”小文心想,同时很快就写出了一份程序,可是测试时却出现了错误
小文很快意识到,她的程序里的变量都是 int
类型的。在大多数机器上,int
类型能表示的最大数为 2^31−1,因此只要计算结果超过这个数,她的程序就会出现错误
由于小文刚刚学会编程,她担心使用 int
计算会出现问题。因此她希望你在 ab 的值超过 10^9 时,输出一个 -1
进行警示,否则就输出正确的 a^b 的值
然而小文还是不知道怎么实现这份程序,因此她想请你帮忙
[输入格式]
输入共一行,两个正整数 a,b
[输出格式]
输出共一行,如果 a^b 的值不超过 10^9,则输出 a^b 的值,否则输出 -1
[输入输出样例]
输入 #1
10 9
输出 #1
1000000000
输入 #2
23333 66666
输出 #2
-1
说明/提示
数据规模
对于 10% 的数据,保证 b=1。
对于 30%的数据,保证 b≤2。
对于 60% 的数据,保证 b≤30,a^b≤ 10^18。
对于 100% 的数据,保证 1≤a,b≤10^9。
2 相关知识点
1) 常用数据类型
C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型
类型 | 关键字 |
---|---|
布尔型 | bool |
字符型 | char |
整型 | int |
浮点型 | float |
双浮点型 | double |
无类型 | void |
宽字符型 | wchar_t |
取值范围
类型 | 位数(字节) | 范围 |
---|---|---|
char | 8位,1 个字节 | -128 到 127 或者 0 到 255 |
unsigned char | 8位,1 个字节 | 0 到 255 |
signed char | 8位,1 个字节 | -128 到 127 |
int | 32位,4 个字节 | -2147483648 到 2147483647 |
unsigned int | 32位,4 个字节 | 0 到 4294967295 |
signed int | 32位,4 个字节 | -2147483648 到 2147483647 |
short int | 16位,2 个字节 | -32768 到 32767 |
unsigned short int | 16位,2 个字节 | 0 到 65,535 |
signed short int | 16位,2 个字节 | -32768 到 32767 |
long int | 64位,8 个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
signed long int | 64位,8 个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long int | 64位,8 个字节 | 0 to 18,446,744,073,709,551,615 |
float | 32位,4 个字节 | +/- 3.4e +/- 38 (~7 个数字) |
double | 32位,8 个字节 | +/- 1.7e +/- 308 (~15 个数字) |
long double | 128位,16 个字节 | +/- 1.7e +/- 308 (~15 个数字) |
wchar_t | 2 或 4 个字节 | 1 个宽字符 |
2) 数据溢出
在C语言中,数据溢出是指变量在进行计算或赋值操作时超出了其数据类型所能表示的范围,导致结果不正确或不可预料的行为
#include<bits/stdc++.h>
using namespace std;
int main(){
char c=129;//超出了char 表示的数值范围 char最大是127
printf("%d",c);
return 0;
}
/*
输出
-127
*/
3) 数据类型转换
在C++中,数据类型转换(也称为类型转换)是将一种数据类型的值转换为另一种数据类型的过程
例如为了保持小数可以将整形转换为浮点型
int a=5;
float b=a;//隐式地将int转换float
数据类型转换有自动类型转换和强制类型转换转换2种
自动类型转换
往数据类型长的方向转换 保证精度不丢失
比如 int和long long 运算会转换成long long
#include<iostream>
using namespace std;
/*
自动类型转换 往数据类型长的方向转换 保证精度不丢失
比如 int和long long 运算会转换成long long
*/
int main(){
int a=4;
long long b=9;
cout<<"a占用字节数: "<<sizeof(a)<<endl;//整形4个字节
cout<<"b占用字节数: "<<sizeof(b)<<endl;//长整形8个字节
cout<<"a+b占用字节数: "<<sizeof(a+b)<<endl; //长整形8个字节
return 0;
}
/*
a占用字节数: 4
b占用字节数: 8
a+b占用字节数: 8
*/
赋值运算
在赋值运算中,赋值号两边的数据类型不相同时,把右边表达式的值的类型转换为左边变量的类型,如果把右边表达式的值数据类型长度比左边长,将丢失一部分数据
#include<iostream>
using namespace std;
int main(){
double d = 123.45;
int i = d; // i现在是123,小数部分被丢弃
cout<<"整型i的值为: "<<i<<endl;
return 0;
}
/*
整型i的值为: 123
*/
强制类型转换
当自动类型转换不能转换时,可以显示进行类型转换,称强制类型转换
#include<iostream>
using namespace std;
/*
求2个数之和
*/
int main(){
int a=2147483647;
int b=10;
long long c= (long long ) a + b;//把a的类型从int转换成long long
cout<<"c变量存储超int范围数:"<<c<<endl;//c的结果为2147483657
return 0;
}
/*
c变量存储超int范围数:2147483657
*/
4) 指数
指数是幂运算aⁿ(a≠0)中的一个参数,a为底数,n为指数,指数位于底数的右上角,幂运算表示指数个底数相乘。
当n是一个正整数,aⁿ表示n个a连乘。当n=0时,aⁿ=1
例如
a=2 n=4时
2^4=2 * 2 * 2* 2=16
3 思路分析
1 a的b次方,相当于b个a相乘
2 初始m为1,每次m乘以a,连续乘b个即为结果,超出最大值输出-1,不超输出m
3 根据数据条件可能超出int的最大范围(2147483647),所以相乘的结果存储long long类型的m中
#include<bits/stdc++.h>
using namespace std;
const int N=1e9;//允许的最大值 超出输出-1
int a,b;//输入a b
long long m=1;//存储 a^b
int main(){
cin>>a>>b;//输入a b
for(int i=0;i<b;i++){//循环b次
m=m*a;//m从1开始每次乘以a
if(m>N){//如果大于允许的最大值 输出-1
cout<<"-1";
return 0;//退出程序
}
}
cout<<m;//输出 a^b
return 0;
}
作者:newcode 更多资源请关注纽扣编程微信公众号
从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习