P8588

题目描述

先是输入 \(x\)\(k\) 两个整数,\(x\)非负整数

\(k\) 则是要进行 \(k\) 轮操作,对于一轮操作,有以下两个步骤:

\(1.\)\(x\) 增加 \(1\)

\(2.\) 如果 \(x\)\(3\) 的倍数,则将 \(x\) 除以 \(3\)

题目分析

刚读完题目描述时,我们肯定已经写了一个初步代码:

#include<iostream>
#include<cstdio>
using namespace std;
long long x,k; 
int main() {
    cin>>x>>k;
    while(k--){
       x++;
       if(x%3==0){
           x/=3;
       }
    }
	cout<<x;
	return 0;
}

可是这个代码交上去后会TLE六个点,那原因在哪里呢?

我们通过仔细读题和分析,发现如果 \(x\)\(1\) 时,变化规律总是这样的:

1->2->(3->1)->2->(3->1)//用括号括起来的为一次操作

如果设 \(x=1\),\(k=5\),而此时我们再列举一下 \(x\)\(k\) 的值:

x 1 2 1 2 1
k 4 3 2 1 0

我们发现 \(x\)\(k\) 的值是有规律可循的,当 \(x=1\) 时,\(k\) 的值为偶数,当 \(x=2\) 时,\(k\) 的值为奇数

而加上这个奇偶判断则大大简化了我们的时间复杂度

这一部分的代码如下:

if(x==1) {
	if(k%2==0) {
		cout<<1<<endl;
		return 0;
	}
	if(k%2==1) {
		cout<<2<<endl;
		return 0;
	}
}

AC 代码

#include<iostream>
#include<cstdio>
using namespace std;
long long x,k;
int main() {
	cin>>x>>k;
	while(k--) {
		x++;
		if(x%3==0) {
			x/=3;
		}
		if(x==1) {
			if(k%2==0) {
				cout<<1<<endl;
				return 0;
			}
			if(k%2==1) {
				cout<<2<<endl;
				return 0;
			}
		}
	}
	cout<<x;
	return 0;
}

posted @ 2022-10-26 19:54  abc_mx  阅读(53)  评论(0)    收藏  举报