【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=6020

【题意】



给你一个长度为n的数字,然后让你删掉k个数字,问你有没有删数方案使得剩下的N-K个数字是3的倍数;

【题解】



这里我们枚举最后N-K个数字它的最高位是第几位;

这样我们就能在枚举最高位的时候直接判断这个数字是不是0;这样对合法性的处理就简单很多了;

我们枚举第i位是最高位,言外之意就是说前i-1个数字已经全部被删掉了;

则我们要在i+1..n这些数字里面再删掉k-i+1个数字才行;

这里设i+1..n这些数字的和对3的取余结果为rest



如果rest为1

我们先在i+1..n里面删掉1个取余结果为1的数字或者在i+1..n里面删掉2个取余结果为2的数字;后续的工作我们等下再说.

如果rest为2

我们先在i+1..n里面删掉1个取余结果为2的数字或者在i+1..n里面删掉2个取余结果为1的数字;

至此我们把问题转换成

在i+1..n里面删掉k-i+1-x个数字(x是我们刚才因为rest不等于0先假设删掉的数字)然后要求i+1..n所有的数字的和%3的结果为0;

这里我们只要考虑1+2和0两种形式了;

对于1+2类型的,我们只要考虑最多出现2组配对;

即两组1+2

因为如果你出现了3组1+2,其实也就是3个1和3个2了;

所以我们枚举出现了几组”1+2”类型->i然后i∈[0..2]

然后1剩下r1-i个,2剩下r2-i个,然后1能够选(r1-i)/3*3个,2能够选(r2-i)/3*3个;

之所以3个3个地选,是保证删除这些数字之后取余结果仍然保持0;

然后3个3个地选完之后,再看看余为0的个数有多少个;看够不够凑足k-i+1-x个数字;够的话就可行;

这里没办法考虑到删掉n-1个数字然后结果为0的情况;

所以要特判.



【完整代码】

#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;
}

【BestCoder Round #93 1002】MG loves apple的更多相关文章

  1. 【BestCoder Round #93 1001】MG loves gold

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=6019 [题意] 每次选择一段连续的段,使得这一段里面没有重复的元素; 问你最少选多少次; [题解] ...

  2. 【BestCoder Round #93 1004】MG loves set

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=6022 [题意] 让你求一个集合的子集数目; 这个子集有要求; 即: 它所有元素的平方的和小于它所有 ...

  3. 【HDU 6020】 MG loves apple (乱搞?)

    MG loves apple  Accepts: 20  Submissions: 693  Time Limit: 3000/1500 MS (Java/Others)  Memory Limit: ...

  4. 贪心/二分查找 BestCoder Round #43 1002 pog loves szh II

    题目传送门 /* 贪心/二分查找:首先对ai%=p,然后sort,这样的话就有序能使用二分查找.贪心的思想是每次找到一个aj使得和为p-1(如果有的话) 当然有可能两个数和超过p,那么an的值最优,每 ...

  5. 暴力+降复杂度 BestCoder Round #39 1002 Mutiple

    题目传送门 /* 设一个b[]来保存每一个a[]的质因数的id,从后往前每一次更新质因数的id, 若没有,默认加0,nlogn复杂度: 我用暴力竟然水过去了:) */ #include <cst ...

  6. 矩阵快速幂---BestCoder Round#8 1002

    当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n)   f(n-1)] = [f(n ...

  7. Manacher BestCoder Round #49 ($) 1002 Three Palindromes

    题目传送门 /* Manacher:该算法能求最长回文串,思路时依据回文半径p数组找到第一个和第三个会文串,然后暴力枚举判断是否存在中间的回文串 另外,在原字符串没啥用时可以直接覆盖,省去一个数组空间 ...

  8. 二分图判定+点染色/并查集 BestCoder Round #48 ($) 1002 wyh2000 and pupil

    题目传送门 /* 二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no 每一次二分图匹配时,将点多的集合加大最后第一个集合去 注意:n <= 1,no,两 ...

  9. hdu 6020 MG loves apple 恶心模拟

    题目链接:点击传送 MG loves apple Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Ja ...

随机推荐

  1. redis书籍

    redis中文官网命令网址:http://doc.redisfans.com/ redis英文官网命令网址:https://redis.io/commands redis书籍 由 Karl Segui ...

  2. bzoj4974: [Lydsy八月月赛]字符串大师

    传送门 题目可转换为已知一个串kmp之后的nxt数组,求字典序最小的原串. 已知第i位结尾的串循环节长度位x,那么nxt[i]=i-x; 当nxt不为0时,s[i]=s[nxt[i]]; nxt为0时 ...

  3. POJ 2311 博弈

    #include<stdio.h> #include<string.h> #include<set> using namespace std; ][]; int s ...

  4. vue渲染学生信息

    渲染学生信息 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  5. Leetcode693.Binary Number with Alternating Bits交替位二进制数

    给定一个正整数,检查他是否为交替位二进制数:换句话说,就是他的二进制数相邻的两个位数永不相等. 示例 1: 输入: 5 输出: True 解释: 5的二进制数是: 101 示例 2: 输入: 7 输出 ...

  6. redis是当前流行的nosql数据库

    redis是当前流行的nosql数据库,很多网站都用它来做缓存,今天我们来安装并配置下redis 二.安装并配置redis 1.安装redis sudo apt-get install redis-s ...

  7. 重温Observer模式--热水器·改

    引言 在 C#中的委托和事件 一文的后半部分,讲述了Observer(观察者)模式,并使用委托和事件实现了这个模式.实际上,不使用委托和事件,一样可以实现Observer模式.在本文中,我将使用GOF ...

  8. 阿里云应用高可用 AHAS 正式商用,可一键提升云上应用可用性

    在分布式架构环境下,服务间的依赖日益复杂,可能没有人能说清单个故障对整个系统的影响,构建一个高可用的分布式系统面临着很大挑战. 7月17日,阿里云应用高可用服务AHAS 正式商用,包含架构感知.流控降 ...

  9. QT语言翻译

    QT中多语言的实现方式: 1.代码中tr运用 2.使用工具生成ts文件 3.翻译ts文件 4.生成qm文件 5.程序加载 以下内容程序加载时放入即可. QString appPath = QCoreA ...

  10. firefox扩展开发(一) : 扩展的基本结构

    用过firefox的人肯定要安装firefox的扩展,这样才能发挥火狐的全部实力.一般扩展是一个后缀为.xpi的文件,其实这个文件就是zip格式的压缩包,压缩了一个扩展所需要的所有目录和文件,基本的目 ...