【题解】「CF1175A」From Hero to Zero

题目

题目描述

You are given an integer n n n and an integer k k k .

In one step you can do one of the following moves:

  • decrease n n n by 1 1 1 ;
  • divide n n n by k k k if n n n is divisible by k k k .

For example, if n = 27 n = 27 n=27 and k = 3 k = 3 k=3you can do the following steps: 27 → 26 → 25 → 24 → 8 → 7 → 6 → 2 → 1 → 0 27 \rightarrow 26 \rightarrow 25 \rightarrow 24 \rightarrow 8 \rightarrow 7 \rightarrow 6 \rightarrow 2 \rightarrow 1 \rightarrow 0 27262524876210

You are asked to calculate the minimum number of steps to reach 0 0 0 from n n n.

输入格式

The first line contains one integer t t t ( 1 ≤ t ≤ 100 1 \le t \le 100 1t100 ) — the number of queries.

The only line of each query contains two integers n n n and k k k ( 1 ≤ n ≤ 1 0 18 1 \le n \le 10^{18} 1n1018 , 2 ≤ k ≤ 1 0 18 2 \le k \le 10^{18} 2k1018).

输出格式

For each query print the minimum number of steps to reach 0 0 0 from n n n in single line.

翻译

给整数 n , k n,k n,k,每次你可以做如下两个操作之一

  • n n n 1 1 1

  • n n n 除以 k k k (前提: n n n k k k 的倍数)

试求让 n n n 变为 0 0 0 的最小操作次数。

输入输出样例

输入

2
59 3
1000000000000000000 10

输出

8
19

题解

一道水题,贪心+一点点简单的优化即可

基本贪心思路

过程

对于每一个 n n n:

  • 如果 n n n k k k的倍数,则进行 n / k n/k n/k的操作,操作数 + 1 +1 +1
  • 否则 n − 1 n-1 n1,操作数 + 1 +1 +1

这样做一定最优

证明

贪心贪就完了,给什么证明(bushi

如果在明明能用 n / k n/k n/k的时候使用了 n − 1 n-1 n1

这样减完后就不可能再用 n / k n/k n/k的操作,直到减了 k k k次,此时 n n n变为 n − k n-k nk,而如果你依然不金盆洗手,还这样干,就需要连减很多次才可以到达 n / k n/k n/k,而人家一次就到了

如果你认识到了错误,不再一个一个减,开始使用除的办法

现在 n − k n-k nk变为 ( n − k ) / k (n-k)/k (nk)/k,即 n / k + 1 n/k+1 n/k+1,跟前面的 n / k n/k n/k还差 1 1 1步,这还不算上之前白白浪费了这么多步

所以,该选择 n / k n/k n/k的时候还是选择TA吧

代码实现

有了思路,代码实现还不简单吗?

#include
#include
using namespace std;
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		long long n,k;
		scanf("%lld %lld",&n,&k);
		long long tot=0;
		while(n!=0){
			if(n%k==0){
				n/=k;
				tot++;
			}
			else{
				n--;
				tot++;
			}
		}
		printf("%lld\n",tot);
	}
return 0;
} 

于是,这个简单的代码就这样简简单单的TLE掉了

【题解】「CF1175A」From Hero to Zero_第1张图片
什么情况?考虑优化

优化

那里一点一点吧 n n n减少成 k k k的倍数的地方是不是有点蛋疼?

我们就不能直接把 n n n一步变为 k k k的倍数吗

想到这里,你距离AC就只剩一步了!

每次如果 n n n不是 k k k的倍数,就直接把 n n n减成 k k k的倍数,并加上相应的步数

代码

#include
#include
using namespace std;
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		long long n,k;
		scanf("%lld %lld",&n,&k);
		long long tot=0;
		while(n!=0){
			if(n%k==0){
				n/=k;
				tot++;
			}
			else{
				long long mm=n%k;
				n-=mm;
				tot+=mm;
			}
		}
		printf("%lld\n",tot);
	}
return 0;
}

The End

你可能感兴趣的:(贪心,思维)