【题解】洛谷-P6581 远大目标

P6581 远大目标 题解

1. 题面分析

2. 做法

2.1 Python做法

2.2 C++做法


1. 题面分析

观察题目,通过绝对值的知识,我们对 (operatorname{sum}(A)) 的取值进行一个分析,易得(请自证):

sum(A)指满足条件的A的个数

[operatorname{sum}(A)=egin{cases}2*O-1(O>0)\0(Oleqslant0)end{cases} ]

所以,这道题只需要简单的计算就行了吗?

当我们看到Subtask 3的数据时,连ull也无能为力...
高精是必须的。


2.做法

高精度就是模拟你列竖式计算的过程 小学上过就行

如果不太懂,可以结合C++题解里的注释分析。

2.1 Python做法

说到高精度,你一定想到了Python。

毕竟Python自带高精度,可以偷懒水题

初学者应该都可以看懂。

代码:

a = int(input())
if a>0:
    print(a*2-1)
else:
    print(0)

2.2 C++做法

C++没有自带高精度,所以,手打吧!

本质是模拟进位,退位。

代码:

#include<bits/stdc++.h>//万能头
using namespace std;
int digit[30];//模拟数位的数组
int main(){
	string s;
	cin>>s;//由于读不了数字,读一个string
	digit[0]=s.length();//个人习惯把长度放digit[0]里
	int flag=0;//用来检测是否全都是0 P.S.:例如0000这种 但是数据貌似没有
	for(int i=0;i<s.length();i++){//枚举0
		if(s[i]!='0')flag=1;
	}
	if(flag==0){//如果是0,答案显然是0
		cout<<0;
		return 0;
	}
	if(s[0]=='-'){//负数也是0
		cout<<0;
		return 0;
	}
	for(int i=0;i<s.length();i++){
		digit[s.length()-i]=s[i]-'0';//!注意,这里要倒着存,进位才方便
	}
	for(int i=1;i<=digit[0];i++){
		digit[i]=digit[i]*2;//翻倍,实现O*2
	}
	for(int i=1;i<=digit[0];i++){//来实现进位
      //为什么要分开?进位的时候进的1不然也会被*2
		if(digit[i]>=10){
			digit[i]-=10;
			digit[i+1]+=1;
		}
	}
	if(digit[digit[0]+1]==1)digit[0]++;//自己理解一下,看最高后面有没有进位,如果有,长度+1
	digit[1]--;//实现2*O-1的-1
	for(int i=1;i<=digit[0];i++){//防止-1的情况,借一位
		if(digit[i]<0){
			digit[i]+=10;
			digit[i+1]-=1;
		}
	}
	if(digit[digit[0]]==0)digit[0]--;//如果最高位退到了0,长度-1
	for(int i=digit[0];i>=1;i--){
		cout<<digit[i];//之前反着存储,所以要反着输出
	} 
	return 0;
}
原文地址:https://www.cnblogs.com/haraki/p/solution_luogu_p6581.html