L1-8 字符串拆分
分数 20
全屏浏览题目
切换布局
作者 JMU-ACMer
单位 集美大学
有一个仅包含0到9的字符串,现在要你将字符串拆分成两个或者以上的非空子字符串,使得子字符串的数值按降序排列,并且相邻的两个子字符串的数值之差为1。
例如:
- 在字符串
9876
可以拆解成["9","8","7","6"],数值为[9,8,7,6] - 在字符串
001
可以拆解成["0","01"],数值为[0,1],或者拆分为["00","1"],数值为[0,1]
如果可以按照上述要求把字符串进行拆分,则输出yes,否则输出no
输入格式:
第一行有一个n,表示字符串的个数(n<=10)
接下去n行,每行一个仅由0到9组成的字符串
每个字符串长度不超过2000。
拆分后的每个数值不会超过1e11
输出格式:
对于每个字符串,若能按照求拆分,则输出yes,否则输出no
输入样例:
4
1234
040032
10009998
4321
输出样例:
no
yes
yes
yes
我们先说一下思路 读取一个字符串,然后判断他的后面几个位 要让他降序排序 比如4321
10009998 里边的100 099 98 (099=98)
就拿10009998这个例子来说 我们一开始拿到这个字符串肯定是按照下面的步骤
从 1开始 ,然后去跟0比较,(1==0+1)好可以,然后再取出下一个0,(0==0)不满足了,然后就要从10开始,
然后取出0不行,(10> 0),不行,然后从剩下的字符串009998从再取出一个0,(10>00),还是不行,然后再取出一个9.(10==009+1)满足了,然后这时候前置位替换成为了9(就是后面的数字要比9小1)然后剩下的从998中开始,显然后面的字符串并不能形成满足题目的条件,这时候又要回到开始,从100开始,循环上面的步骤最后比较成功
从上面的步骤可以看出来,显然是要用递归的代码来完成的,(比如在1000998,在100和099比较完成之后,然后从头开始 在099和98之前开始在做比较)
递归代码:
bool fenge2(vector<string> s1,string s2) {
if(s2.empty()) return true;
for(int i = 1;i<=s2.length();i++){
long long num1 = stoll(s1.back());
long long num2 = stoll(s2.substr(0,i));
if(num1 == num2 + 1)
{
s1.push_back(s2.substr(0,i));
if(fenge2(s1,s2.substr(i))) return true;
else s1.pop_back();
}
}
return false;
}
整体完成代码:
#include<bits/stdc++.h>
using namespace std;
bool fenge2(vector<string> s1,string s2) {
if(s2.empty()) return true;
for(int i = 1;i<=s2.length();i++){
long long num1 = stoll(s1.back());//把字符串转化成longlong型整数
long long num2 = stoll(s2.substr(0,i));
if(num1 == num2 + 1)
{
s1.push_back(s2.substr(0,i));
if(fenge2(s1,s2.substr(i))) return true;
else s1.pop_back();//如果不满足条件,把已经吞入的字符串吐出来
}
}
return false;
}
bool fenge(string str){
vector<string> s1;
for(int i = 1;i<str.size();i++)
{
if(!s1.empty()) s1.clear();
s1 .push_back(str.substr(0,i));
if(fenge2(s1,str.substr(i)))
return true;
}
return false;
}
int main(){
int n;
cin>>n;
string s1;
for(int i = 0;i<n;i++)
{
cin>>s1;
if(fenge(s1))
cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
}
运行样例: