您的位置:首页 > 移动开发

【BestCoder Round #93】hdu6020 MG loves apple

2017-04-02 17:19 288 查看
Problem Description MG is a rich boy. He has n apples, each has a

value of V(0<=V< =9).

A valid number does not contain a leading zero, and these apples have

just made a valid N digit number.

MG has the right to take away K apples in the sequence, he wonders if

there exists a solution: After exactly taking away K apples, the valid

N−K digit number of remaining apples mod 3 is zero.

MG thought it very easy and he had himself disdained to take the job.

As a bystander, could you please help settle the problem and calculate

the answer?

Input The first line is an integer T which indicates the case

number.(1<=T<=60)

And as for each case, there are 2 integer N(1<=N<=100000),K(0<=K< N) in

the first line which indicate apple-number, and the number of apple

you should take away.

MG also promises the sum of N will not exceed 1000000。

Then there are N integers X in the next line, the i-th integer means

the i-th gold’s value(0<=X<=9).

Output As for each case, you need to output a single line.

If the solution exists, print”yes”,else print “no”.(Excluding

quotation marks)

首先知道问题等价于剩下的数字和是3的倍数。

扫描一遍,记下0、余数是1、余数是2、余数是0且非0的个数,以及第一个出现的后三者之前有多少个0。

枚举余数是2的数删掉多少个,可以求出要保证不越界,对应的余数是1的数需要删掉的个数的范围。接下来考虑不能有前导零,这就需要保证余数是1或者余数是2或者余数是0且非0中至少有一个没有被删干净,而且之前的0的个数比删掉的0的个数少【因为0一定从前往后删,非0的数一定从后往前删】。

说起来很麻烦,但是代码不难写。注意特判只剩下0的情况,这也是合法的。

感觉官方题解做法很繁琐,而且有问题,比如数据

6 2

201011

当然也可能是我理解错了意思。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[100010];
int a[100010],n,k;
bool solve()
{
int cnt0=0,cnt1=0,cnt2=0,cnt369=0,before1=0,before2=0,before369=0,sum,x,mnj,mxj;
scanf("%d%d",&n,&k);
scanf("%s",s+1);
for (int i=1;i<=n;i++) a[i]=s[i]-'0';
for (int i=1;i<=n;i++)
{
if (a[i]%3==1) cnt1++;
if (a[i]%3==2) cnt2++;
if (a[i]%3==0)
{
if (!a[i])
{
cnt0++;
if (!cnt1) before1++;
if (!cnt2) before2++;
if (!cnt369) before369++;
}
else cnt369++;
}
}
sum=(cnt1+cnt2*2)%3;
if (k==n-1&&cnt0+cnt369) return 1;
for (int i=0;i<=cnt2;i++)
{
x=((sum-2*i)%3+3)%3;
mnj=max(0,k-i-cnt0-cnt369);
mxj=min(cnt1,k-i);
while (mnj%3!=x) mnj++;
while (mxj>=0&&mxj%3!=x) mxj--;
if (mnj>mxj) continue;
if (before369<=k-i-mnj) return 1;
if (mnj<cnt1&&before1<=k-i-mnj) return 1;
if (i<cnt2&&before2<=k-i-mnj) return 1;
}
return 0;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
if (solve()) printf("yes\n");
else printf("no\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: