1. 程式人生 > >899D Shovel Sale 數學+思維

899D Shovel Sale 數學+思維

題意:給你1,2,...,n,現在要求取出一對數相加為x。x需要滿足:以最多個9結尾。現在給你n,求這樣的數對有幾個。

*例如,9099算以兩個9結尾

題解:設題意的x最多以k個9結尾。

①先想到要求這個k是多少,可以發現一個特殊的數字5,50,500,...。當n<5時,k=0;當n>=5&&n>50時,k=1;當n>=50&&n<500時,k=2...也就是說x是這一樣一個數:Z999......(0<=Z<=8,後面接上k個9)。

②經過第一步分解成Z個子問題之後,現在要求解子問題的數對。這個求解就可以自己總結出結論了,可以以14這個輸入總結得到。

程式碼:

#include<bits/stdc++.h>
#define debug cout<<"aaa"<<endl
#define d(a) cout<<a<<endl
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define MIN_INT (-2147483647-1)
#define MAX_INT 2147483647
#define MAX_LL 9223372036854775807i64
#define MIN_LL (-9223372036854775807i64-1)
using namespace std;

const int N = 100000 + 5;
const int M = N * N + 5;
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;

int main(){
	LL n,k,temp=1,A,ans=0;
	cin>>n;
	LL num=5;
	//小於5的時候特判,這時候k等於9 
	if(n<5){
		cout<<n*(n-1)/2<<endl;
		return 0;
	}
	//求解最多以幾個9結尾 
	for(int i=1;i<=11;i++){
		if(n<num){
			k=i-1;
			break;
		}
		num*=10;
	}
	num=0;
	for(int i=1;i<=k;i++){
		num=num*10+9;
		temp*=10;
	}
	for(int i=0;i<=8;i++){
		//A就是Z999... 
		//num是999... 
		A=i*temp+num;
		if(n<(A+1)/2){
			break;
		}
		else if(n>(A-1)){
			ans=ans+A/2;
		}
		else{
			ans=ans+(n-(A+1)/2+1);
		}
	}
	cout<<ans<<endl;
	return 0;
}