每日一题0306

每日一题0306

Lionlnuc
Lionlnuc Lv4

R 格式

题目链接:
https://www.luogu.com.cn/problem/P10425
思路:
模拟。高精度
代码:
先来一个 50 分的做法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int qmi(int a,int b)
{
int res=1;
while(b){
if(b&1)res=a*res;
b>>=1;
a=a*a;
}
return res;
}
void solve()
{
int n;
double d;
cin>>n>>d;
d*=qmi(2,n);
cout<<(int)(d+0.5);
}

看到 就知道得用高精度。记录一下小数点的位置。对 乘积可以看作累加。因为乘整数所以小数点的位置不会变。
以下内容复习高精度加减乘除法,会的同学可以直接跳过。

高精度加法

高精度加法的步骤:

  1. 高精度数字利用字符串读入;
  2. 把字符串反转翻转存入两个整型数组 A,B;
  3. 从低位到高位,累加,进位,存余;
  4. 把数组 C 从高位到低位依次输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const int N=100005;
int A[N],B[N],C[N];
int la,lb,lc;
void add(int A[],int B[],int C[]){
for(int i=0;i<lc;i++)
{
C[i]+=A[i]+B[i];//累加
C[i+1]+=C[i]/10;//进位
C[i]%=10;//存余
}
if(C[lc])lc++;//处理最高位
}
void solve()
{
string a,b;
cin>>a>>b;
la=a.size(),lb=b.size(),lc=max(la,lb);
for(int i=la-1;i>=0;i--){
A[la-1-i]=a[i]-'0';//将字符形数字转化为数值
}
for(int i=lb-1;i>=0;i--){
B[lb-1-i]=b[i]-'0';//将字符形数字转化为数值
}
//翻转存入方便进位。
add(A,B,C);
for(int i=lc-1;i>=0;i--){
cout<<C[i];
}
}

高精度减法

高精度减法的步骤:

  1. 高精度数字利用字符串读入;
  2. 把字符串反转翻转存入两个整型数组 A,B;
  3. 若 A<B,则交换 A, B,输出负号;
  4. 从低位到高位,逐位求差,借位,存差;
  5. 把数组 C 从高位到低位依次输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const int N=100005;
int A[N],B[N],C[N];
int la,lb,lc;
bool cmp(int A[],int B[]){
if(la!=lb)return la>lb;
for(int i=la-1;i>=0;i--){
if(A[i]!=B[i])return A[i]>B[i];
}
return true;
}
void sub(int A[],int B[],int C[]){
for(int i=0;i<lc;i++)
{
if(A[i]<B[i])
{
A[i+1]--;
A[i]+=10;
}
C[i]=A[i]-B[i];
}
while(lc&&C[lc]==0)lc--;
}
void solve()
{
string a,b;
cin>>a>>b;
la=a.size(),lb=b.size(),lc=max(la,lb);
for(int i=la-1;i>=0;i--){
A[la-1-i]=a[i]-'0';//将字符形数字转化为数值
}
for(int i=lb-1;i>=0;i--){
B[lb-1-i]=b[i]-'0';//将字符形数字转化为数值
}
//翻转存入方便进位。
if(!cmp(A,B))swap(A,B),cout<<"-";
sub(A,B,C);
for(int i=lc;i>=0;i--){
cout<<C[i];
}
}

高精度乘法

高精度乘法的步骤:

  1. 高精度数字利用字符串读入;
  2. 把字符串反转翻转存入两个整型数组 A,B;
  3. 从低位到高位,累加乘积,进位,存余;
  4. 把数组 C 从高位到低位依次输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const int N=100005;
int A[N],B[N],C[N];
int la,lb,lc;
void mul(int A[],int B[],int C[]){
for(int i=0;i<la;i++)
{
for(int j=0;j<lb;j++)
{
C[i+j]+=A[i]*B[j];//累加乘积
C[i+1+j]+=C[i+j]/10;//进位
C[i+j]%=10;//存余
}
}
while(lc&&C[lc]==0)lc--;//处理前导0
}
void solve()
{
string a,b;
cin>>a>>b;
la=a.size(),lb=b.size(),lc=la+lb;
for(int i=la-1;i>=0;i--){
A[la-1-i]=a[i]-'0';//将字符形数字转化为数值
}
for(int i=lb-1;i>=0;i--){
B[lb-1-i]=b[i]-'0';//将字符形数字转化为数值
}
//翻转存入方便进位。
mul(A,B,C);
for(int i=lc;i>=0;i--){
cout<<C[i];
}
}

高精度除法

高精度乘法的步骤:

  1. 高精度数字利用字符串读入;
  2. 把字符串反转翻转存入两个整型数组 A,B;
  3. 从高位到低位,当前被除数,存商,求余数;
  4. 把数组 C 从高位到低位依次输出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const int N=100005;
int A[N],C[N];
int la,b,lc;
void div(int A[],int b,int C[]){
int r=0;
for(int i=la-1;i>=0;i--)
{
r=r*10+A[i];//被除数
C[la-1-i]=r/b;//存商
r%=b;//余数
}
reverse(C,C+lc);
while(lc&&C[lc]==0)lc--;//处理前导0
}
void solve()
{
string a;
cin>>a>>b;
la=a.size(),lc=la;
for(int i=la-1;i>=0;i--){
A[la-1-i]=a[i]-'0';//将字符形数字转化为数值
}
//翻转存入方便进位。
div(A,b,C);
for(int i=lc;i>=0;i--){
cout<<C[i];
}
}

正解代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define PII pair<int,int>
void add(string &a,string &b){
int t=0;
for(int i=0;i<a.size();i++){
t+=a[i]-'0'+b[i]-'0';
a[i]=t%10+'0';
t/=10;
}
if(t){
a.push_back('1');
}
}
void solve()
{
int n;
string d;
cin>>n>>d;
string s;
int p;
//逆序存储并记录小数点位置
for(int i=d.size()-1,j=0;i>=0;i--)
{
if(d[i]!='.')
{
s.push_back(d[i]);
j++;
}else{
p=j-1;//小数点后一位位置
}
}
for(int i=1;i<=n;i++)
{
add(s,s);
}
if(s[p]>='5'){
string b(s.size(),'0');
b[p+1]='1';
add(s,b);
for(int i=s.size()-1;i>p;i--){
cout<<s[i];
}
}else{
for(int i=s.size()-1;i>p;i--){
cout<<s[i];
}
}
}
signed main(){
IOS
//int t;
//cin>>t;
int t=1;
while(t--)
{
solve();
}
}
  • 标题: 每日一题0306
  • 作者: Lionlnuc
  • 创建于 : 2026-03-06 00:00:00
  • 更新于 : 2026-03-06 00:00:00
  • 链接: https://lionlnuc.github.io/2026/03/06/每日一题03.06/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论