题意:
给你一个大数,长度最大是10w, 要求你删除最小的数字使得这个数不含前导零 并且能整除3.
思路:
贪心:
我们知道 如果一个数 的各个数字之和sum 能整除3 的话,那么这个数就是3 的倍数。
我们先判断 sum % 3 是否等于0 等于0 直接输出。
不等于0 的话, 假设是x 的话,那么另一个相对的是y (y = 3-x)
那么我们可以找到一个数字 他的mod 3 = x 或者删除两个数它的mod 3 = y。
两种方式选择一个最大的即可。
注意前导0 的问题。
#include <bits/stdc++.h>
#define Siz(x) (int)x.size()
using namespace std;
const int maxn = 1e5 + 7;
string s;
int main(){
ios::sync_with_stdio(false);
cin >> s;
int len = Siz(s);
int sum = 0;
for (int i = 0; i < len; ++i){
sum += s[i] - 48;
}
sum %= 3;
if (sum == 0) {
cout << s << endl;
return 0;
}
string ans = "-1";
int MAX = 0;
string tmp = "",tmp2 = "";
for (int i = Siz(s); i >= 0; --i){
int v = s[i] - 48;
if (v % 3 == sum){
for (int j = 0; j < i; ++j) tmp += s[j];
for (int j =i+1; j < len; ++j) tmp += s[j];
int cur = 0;
while(tmp[cur] == 48)++cur;
if (cur != Siz(tmp)){
while(cur != Siz(tmp)){
tmp2 += tmp[cur];
++cur;
}
if (Siz(tmp2) > MAX){
MAX = Siz(tmp2);
ans = tmp2;
}
}
else {
if (Siz(tmp) > 0) {
if (1 > MAX){
MAX = 1;
ans = "0";
}
}
}
break;
}
}
int p1 = -1;
tmp = tmp2 = "";
for (int i = Siz(s); i>= 0; --i){
int v = s[i] - 48;
if (v % 3 == 3-sum){
if (p1 == -1) {
p1=i;
continue;
}
for (int j = 0; j < i; ++j) tmp += s[j];
for (int j = i+1; j < p1; ++j) tmp+= s[j];
for (int j =p1+1; j < len; ++j) tmp+=s[j];
int cur = 0;
while(tmp[cur] == 48)++cur;
if (cur != Siz(tmp)){
while(cur != Siz(tmp)){
tmp2 += tmp[cur];
++cur;
}
if (Siz(tmp2) > MAX){
MAX = Siz(tmp2);
ans = tmp2;
}
}
else {
if (Siz(tmp) > 0) {
if (1 > MAX){
MAX = 1;
ans = "0";
}
}
}
break;
}
}
cout << ans << endl;
return 0;
}