CodeForces 792C - Divide by Three [ 分类讨论 ]

删除最少的数位和前缀0,使得剩下的数能被3整除

等价于各数位数字之和能被3整除。

当前数位和可能是 0, 1, 2(mod 3)

  0: 直接处理

  1: 删除一个a[i]%3 == 1 或者 两个a[i]%3 == 2

  2: 同1

对于删完的数列,去掉前置0(只剩前置0就当作0)

若删啥都不满足,则判断原数列中有没有0,不然就输出-1

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN = 100005;
 4 char s[MAXN];
 5 int a[MAXN], n;
 6 string ans, tmp;
 7 int b[MAXN], m;
 8 void Update()
 9 {
10     tmp.clear();
11     int i;
12     for (i = 1; i <= m && !b[i]; i++);
13     if (i < m+1)
14     {
15         for (i; i <= m; i++)
16             tmp += b[i] + ‘0‘;
17     }
18     else if (m)
19         tmp += ‘0‘;
20     if (ans.length() < tmp.length())
21         ans = tmp;
22 }
23 int main()
24 {
25     scanf("%s", s);
26     n = strlen(s);
27     for (int i = 1; i <= n; i++)
28         a[i] = s[i-1] - ‘0‘;
29     int sum = 0;
30     for (int i = 1; i <= n; i++)
31         sum = (sum+a[i]%3) % 3;
32     if (!sum)
33     {
34         m = 0;
35         for (int i = 1; i <= n; i++)
36             b[++m] = a[i];
37         Update();
38     }
39     else
40     {
41         int p1 = 0, p2 = 0;
42         for (int i = n; i > 0 && !p1; i--)
43             if (a[i]%3 == sum) p1 = i;
44         if (p1)
45         {
46             m = 0;
47             for (int i = 1; i <= n; i++)
48             {
49                 if (i == p1) continue;
50                 b[++m] = a[i];
51             }
52             Update();
53         }
54         p1 = p2 = 0;
55         for (int i = n; i > 0 && (!p1 || !p2) ; i--)
56             if (a[i]%3 +sum == 3) p1 ? p2 = i : p1 = i;
57         if (p1 && p2)
58         {
59             m = 0;
60             for (int i = 1; i <= n; i++)
61             {
62                 if (i == p1 || i == p2) continue;
63                 b[++m] = a[i];
64             }
65             Update();
66         }
67     }
68     if (!ans.length())
69     {
70         bool flag = 0;
71         for (int i = 1; i <= n; i++)
72             if (!a[i]) flag = 1;
73         puts(flag? "0": "-1");
74     }
75     else cout << ans << endl;
76 }

时间: 2025-01-14 03:31:30

CodeForces 792C - Divide by Three [ 分类讨论 ]的相关文章

codeforces 792C. Divide by Three

题目链接:codeforces 792C. Divide by Three 今天队友翻了个大神的代码来问,我又想了遍这题,感觉很好,这代码除了有点长,思路还是清晰易懂,我就加点注释存一下...分类吧.删除一个数字模3为M的或删除两个模3为3-M的(还有一些要删零),具体看代码. #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<strin

Codeforces 506D Mr. Kitayuta&#39;s Colorful Graph 并查集+水水的分类讨论+水水的离线预处理

首先读入所有的边与询问.将边按颜色分类. 按颜色进行并查集, 若此并查集内的点<= 100,则100*100/2的枚举是否联通. 若此并查集内的点  > 100,则将与这些点相关的所有询问查一遍. 那么时间复杂度为100*100/2*(M/100),或者为M/100*Q. 极限的时候两种方法都在一亿左右了,而且每次还需要在map里搞一搞,还要查询是否联通,不知道为啥没有超时.. #include <algorithm> #include <iostream> #incl

【推导】【分类讨论】Codeforces Round #431 (Div. 1) B. Rooter&#39;s Song

给你一个这样的图,那些点是舞者,他们每个人会在原地待ti时间之后,以每秒1m的速度向前移动,到边界以后停止.只不过有时候会碰撞,碰撞之后的转向是这样哒: 让你输出每个人的停止位置坐标. ①将x轴上初始坐标记为(pi,0),y轴上的初始坐标记为(0,pi).只有pi-ti相同的才有可能发生碰撞.于是可以按照这一点将人划分为很多组,不同组之间绝对不会互相影响. ②假设一组内每个人都不会发生碰撞,那么所有的路线交叉点都是碰撞点.所以碰撞次数可能达到n^2次,暴力不可行. ③对于一组内,形成了一个网格图

Codeforces 460D Little Victor and Set --分类讨论+构造

题意:从区间[L,R]中选取不多于k个数,使这些数异或和尽量小,输出最小异或和以及选取的那些数. 解法:分类讨论. 设选取k个数. 1. k=4的时候如果区间长度>=4且L是偶数,那么可以构造四个数(L,L+1,L+2,L+3),这样的话(L^(L+1)) ^ ((L+2)^(L+3)) = 0,最优 如果L不是偶数,那么看从L+1到R有没有四个数,如果有则取该四个数,否则最小异或和达不到0,也达不到1了,不再考虑k=4,k=3时还有可能等于0,所以转到k=3 2. k=3时,要使异或和为0,那

【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树--但是会TLE. LCT一样无脑,但是少一个log,可以过. 正解是分类讨论, 如果t不在lca(s,f)的子树内,答案是dis(lca(s,f),f). 如果t在lca(s,f)的子树内,并且dep(lca(s,t))>dep(lca(f,t)),答案是dis(lca(s,t),f): 否则答案是dis(lca(f,t),f). #in

dp+分类讨论 Gym 101128E

题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/details/61428924 Description n个小木条,一段前面有一个小箭头,给出第一个小木条的非箭头端端点横坐标以及每个小木条箭头端的坐标,现在要从下往上把这n'个木条按顺序叠放好,要求相邻两个小木条必须有一个共同端点且有交叠部分,问小木条有多少种放法 Input 第一行一整数n表示木条数量,之

cf 251 B Playing with Permutations 暴力 分类讨论

题链;http://codeforces.com/problemset/problem/251/B B. Playing with Permutations time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Little Petya likes permutations a lot. Recently his mom has p

【线段树】【分类讨论】水果姐逛水果街Ⅰ

3304 水果姐逛水果街Ⅰ 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 水果姐今天心情不错,来到了水果街. 水果街有n家水果店,呈直线结构,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样. 学过oi的水果姐迅速发现了一个赚钱的方法:在某家水果店买一个水果,再到另外一家店卖出去,赚差价. 就在水果姐窃喜的时候,cgh突然出现,他为了为难水果姐,给出m个问题,每个问题要求水果姐从第x家店出发到第y家店

BZOJ 1067 降雨量(RMQ+有毒的分类讨论)

1067: [SCOI2007]降雨量 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 4399  Solved: 1182 [Submit][Status][Discuss] Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格小于X年.例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890, 则可以说