CF1626B Minor Reduction 题解
想获得更好的阅读体验?没有哦,你什么也不能戳。
题面
分析
通过题目的描述,我们很容易可以发现每次替换有两种可能。第一种可能为两位数替换两位数,第二种可能为一位数替换两位数。我们分情况来讨论
- 两位数替换两位数,我们将对原数字进行操作的两位分别记为 \(i\),\(j\)。即第 \(i\) 位加上第 \(j\) 位大于 \(10\)。很显然,进行一次这样的操作后,从被操作的数字开始,操作后的数字一定比原数字小,所以我们希望操作的位置在越后面越好,这样对数字减小的影响最小。
- 一位数替换两位数,我们将对原数字进行操作的两位分别记为 \(i\),\(j\)。即第 \(i\) 位加上第 \(j\) 位小于 \(10\)。很显然,进行了一次这样的操作后,整个数字会少一位,比原数字小。但是如果我们看第 \(i\) 位和第 \(j\) 位,可以发现对他们操作后产生的数字一定一定大于等于 \(i\) 和 \(j\)。既然一定会少一位,那么我们需要在少一位的基础上最大,所以,我们希望操作的地方越前面越好,这样越前面的位越大,整个数也越大。
注意用两位数替换两位数结果一定是比一位数替换两位数的结果大的!因为前者会多一位,所以我们可以先判断能否进行两位数替换两位数,不行再去考虑一位数替换两位数。
代码
分析结束,上代码
#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
while(n--)
{
string s;
cin >> s;
int flag = -1;
for (int i=0 ; i<s.size()-1 ; i++)
{
if ((s[i]-'0'+s[i+1]-'0')>=10)
{
flag = i; //记录可以进行两位数替换两位数操作的位置,
//由于是从前往后扫的,且我们希望
//越后越好,所以只要有新的
//可以满足的就可以替换前面的
}
}
if (flag!=-1) // 如果可以进行两位数替换两位数操作就进行
{
int sum = s[flag]-'0'+s[flag+1]-'0';
for (int i=0 ; i<flag ; i++)
{
cout << s[i];
}
cout << sum;
for (int i=flag+2 ; i<s.size() ; i++)
{
cout << s[i];
}
cout << endl;
continue;
}
else //进行一位数替换两位数的操作,因为越前越好,
//所以一定是对最前面两位进行操作
{
int sum = s[0]-'0'+s[1]-'0';
cout << sum;
for (int i=2 ; i<s.size() ; i++)
{
cout << s[i];
}
cout << endl;
}
}
return 0;
}
代码表达的意思在注释里写的都比较清楚了,应该没有理解难度。

浙公网安备 33010602011771号