[Title link] http://acm.hdu.edu.cn/showproblem.php?pid=6020
[title]
Give you a number with length n, and then let you delete k numbers. Ask if you have a deletion plan so that the remaining N-K numbers are multiples of three.
[Abstract]
Here we enumerate the last N-K number, which is the highest number.
In this way, we can directly determine whether the number is zero when enumerating the highest digits; so the processing of legitimacy is much simpler;
We enumerate the number i is the highest, which implies that the first i-1 number has been deleted.
Then we need to delete k-i+1 i n the numbers i+1.n.
Let's set the sum of these numbers to rest.
be
If rest is 1
First, we delete a number with a residual result of 1 i n i+1.n or two numbers with a residual result of 2 i n i+1.n; we will talk about the follow-up work later.
If rest is 2
First, we delete one digit with the result of 2 i n i + 1. n or two digits with the result of 1 i n i + 1. n.
So we turn the problem into a problem.
Delete k-i+1-x numbers i n i+1.n (x is the number we just assumed to delete because rest is not equal to 1) and then ask the sum of all numbers i n i+1.n and% 3 to be 0;
Here we only need to consider two forms: 1 + 2 and 0.
For type 1 + 2, we only need to consider two pairs at most.
That is the two set of 1+2
Because if you have three groups of 1 + 2, it's actually three groups of 1 and three groups of 2.
So we enumerate several groups of "1+2" types - > i and then i <[0.2]
Then 1 left r1-i and 2 left r2-i. Then 1 could choose (r1-i)/3 and 2 could choose (r2-i)/3.
The reason for the three choices is to ensure that after deleting these numbers, the remaining results will remain zero.
Then after three places have been selected, we can see how many of the remaining 0 numbers are; if enough, we can find enough k-i+1-x numbers; if enough, we can do it.
There is no way to consider deleting n-1 numbers and then the result is zero.
So we have to make a special judgment.
[Complete code]
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define ps push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x)
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int N = 1e5+100;
int n, k;
char s[N];
int a[N],t[N],hzh[N][3];
bool ok(int r0, int r1, int r2, int k)
{
if (r0 < 0 || r1 < 0 || r2 < 0 || k < 0) return false;
if (k == 0) return true;
rep1(i, 0, 2)
{
if (r1 < i || r2 < i) break;
if (2 * i > k) break;
int restk = k - 2 * i;
if (restk == 0) return true;
int d = (r1 - i) / 3 * 3 + (r2 - i) / 3 * 3;
if (d < restk)
{
if (d + r0 >= restk) return true;
}
else//d>=restk
{
restk %= 3;
if (r0 >= restk)
return true;
}
}
return false;
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
int T;
rei(T);
while (T--)
{
rei(n), rei(k);
scanf("%s", s + 1);
rep1(i, 1, n)
{
a[i] = s[i] - '0';
t[i] = a[i] % 3;
}
rep1(i, 0, 2) hzh[n + 1][i] = 0;
rep2(i, n, 1)
{
rep1(j, 0, 2) hzh[i][j] = hzh[i + 1][j];
hzh[i][t[i]]++;
}
int rest = (hzh[1][1] + hzh[1][2] * 2) % 3;
bool fi = false;
rep1(i, 1, n)
{
if (a[i] > 0)
{
if (rest == 0 && ok(hzh[i + 1][0], hzh[i + 1][1], hzh[i + 1][2], k - i + 1)) {
fi = true; break;
}
if (rest == 1 && (ok(hzh[i+1][0],hzh[i+1][1]-1,hzh[i+1][2],k-i)||ok(hzh[i+1][0],hzh[i+1][1],hzh[i+1][2]-2,k-i-1))) {
fi = true; break;
}
if (rest == 2 && (ok(hzh[i + 1][0], hzh[i + 1][1] - 2, hzh[i + 1][2], k - i-1) || ok(hzh[i + 1][0], hzh[i + 1][1], hzh[i + 1][2] - 1, k - i))) {
fi = true; break;
}
}
rest = (rest - t[i] + 3) % 3;
}
if (k == n - 1 && hzh[1][0] > 0) fi = true;
if (fi) puts("yes"); else puts("no");
}
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}