赞
踩
整理的算法模板合集: ACM模板
实际上是一个全新的精炼模板整合计划
比赛链接:https://codeforces.com/contest/1478
Problem A - Nezzar and Colorful Balls
给你 n n n 个球 1 ⋯ n 1\cdots n 1⋯n,每个球上有一个数字,所有球上的数字组成的序列经排序以后是一个不下降的数列。我们要为每一个球都染上颜色,保证我们使用的每一种颜色,染上这个颜色的球上的数字组成的序列经排序后一定是严格上升的数列。问我们最少需要多少种颜色才能在符合要求的前提下将所有的球都染上色。
1 ≤ T , n ≤ 100 1\le T,n\le100 1≤T,n≤100
Solution
签到题,只要读懂题意模拟一下样例就行了,我们发现答案就是相同数字的最大个数。因为每个颜色能染的球,球上的数字必须是严格升序而不能是相等,所以也就意味着对于相同数字的球,我们每一种颜色都只能染一个球,最少需要的颜色数量就是相同数字的球的最大数量。我们直接用桶记录一下 ~ 算一下这个最大个数即可。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int N = 50007; int n, m, t; int a[N]; int ans; int vis[N]; int main() { scanf("%d", &t); while(t -- ) { ans = 0; memset(vis, 0, sizeof vis); scanf("%d", &n); for(int i = 1; i <= n; ++ i) { scanf("%d", &a[i]); vis[a[i]] ++ ; } for(int i = 1; i <= n; ++ i) { ans = max(ans, vis[a[i]]); } printf("%d\n", ans); } return 0; }
Problem B Nezzar and Lucky Number
给定 q q q 个正整数,问能不能拆分一个或多个十进制表示法上有 d d d 的正整数。 ( 1 ≤ q ≤ 1 0 4 , 1 ≤ d ≤ 9 1 \le q \le 10^4,1 \le d \le 9 1≤q≤104,1≤d≤9 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109.
Solution
因为数据比较大,这种题目一般数达到一个限制以后,答案就不会变了。
我们发现一旦 x ≥ 10 ∗ d x\ge 10*d x≥10∗d,就一定能被 “幸运数字” 拼出来。
因为 [ 10 ∗ d , 10 ∗ d + 9 ] [10*d,10*d+9] [10∗d,10∗d+9] 都是幸运数字,例如 d = 7 d=7 d=7 [ 70 , 79 ] [70,79] [70,79] 均为幸运数字(均含有 d = 7 d=7 d=7),这样我们在 [ 10 ∗ d , 10 ∗ d + 9 ] [10*d,10*d+9] [10∗d,10∗d+9] 的基础之上,都加上 d d d ,得到 [ 10 ∗ d + d , 10 ∗ d + 9 + d ] → [ 11 ∗ d , 11 ∗ d + 9 ] , ( 1 ≤ d ≤ 9 ) [10*d+d,10*d+9+d] \to [11*d,11*d+9],(1\le d \le 9) [10∗d+d,10∗d+9+d]→[11∗d,11∗d+9],(1≤d≤9) 均为 YES
。而 10 ∗ d + 9 + d 10*d+9+d 10∗d+9+d 的下一位,也就是 10 ∗ d + 9 + d + 1 = 12 ∗ d 10*d+9+d+1=12*d 10∗d+9+d+1=12∗d,同样是幸运数字,这样我们再在 [ 11 ∗ d , 11 ∗ d + 9 ] [11*d,11*d+9] [11∗d,11∗d+9]的基础之上,同样加上 d d d ,以此类推,我们发现只要 x ≥ 10 ∗ d x\ge 10*d x≥10∗d ,答案均为 YES
。
然后我们只需要考虑一下 x ≤ 10 ∗ d x\le10*d x≤10∗d 的情况即可。因为 1 ≤ d ≤ 9 1\le d\le9 1≤d≤9,所以这些数不会很多,我们只需要预处理一下即可。可以直接爆搜,将所有的YES
数字加起来,标记和也为 YES
或者动规,甚至手动打表,因为最多只有几百个数。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <map> #include <vector> using namespace std; const int N = 1e4 + 7, mod = 1e9 + 7; typedef long long ll; int n, m, t, x; map<int, int> ans[N]; int a[N]; bool vis[N]; void solve(int d) { ans[d][0] = 1; int limit = 10 * d; for(int i = 0; 10 * i + d <= limit; ++ i) { for(int j = 0; 10 * i + d + j <= limit; ++ j) { ans[d][10 * i + d + j] |= ans[d][j]; } } ans[d][0] = 0; } void init() { for(int i = 1; i <= 9; ++ i) { solve(i); } } int d; int main() { scanf("%d", &t); init(); while(t -- ) { scanf("%d%d", &n, &d); for(int i = 1; i <= n; ++ i) { int x; scanf("%d", &x); if(x >= 10 * d) { puts("YES"); } else { if(ans[d][x]) { puts("YES"); } else { puts("NO"); } } } } return 0; }
写题解看别人题解的时候发现的一个思路:
我们发现一个结论:
若这是 a i a_i ai 满足: a i − k ⋅ d a_i - k \cdot d ai−k⋅d
其中 k ∈ [ 1 , 9 ] k \in [1,9] k∈[1,9] 的话,它就可以,反则反之。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <map> #include <vector> using namespace std; const int N = 1e4 + 7, mod = 1e9 + 7; typedef long long ll; typedef int itn; itn n, m, q, d; itn t; int a[N]; bool solve(itn x) { if(x >= 10 * d) return true; for(;x >= d; x -= d) if(x % 10 == d) return true; return false; } int main() { scanf("%d", &t); while(t -- ) { scanf("%d%d", &q, &d); for(int i = 1; i <= q; ++ i) { itn x; scanf("%d", &x); if(solve(x)) puts("YES"); else puts("NO"); } } return 0; }
定义长度为 2 × n 2 \times n 2×n 的数组 a a a ,满足:
a a a 中的元素不重复。
并且对于任意一个下标 i ( 1 ≤ i ≤ 2 ⋅ n , i ≠ j ) i(1 \leq i \leq 2 \cdot n, i \ne j) i(1≤i≤2⋅n,i=j),都能找到一个下标 j j j,使得 a i = − a j a_i = -a_j ai=−aj 。
现在给定一个数组 d d d,其中
d i = ∑ j = 1 2 n ∣ a i − a j ∣ d_i = \sum_{j=1}^{2n}|a_i -a_j| di=j=1∑2n∣ai−aj∣
问能不能通过数组 d d d 构造出数组 a a a 。
能构造出输出 YES
,不能就输出 NO
有 T T T 组数据,其中 1 ≤ T ≤ 1 0 5 , 1 ≤ n ≤ 1 0 5 , 1 ≤ d i ≤ 1 0 12 1\le T \le10^5,1\le n \le10^5,1\le d_i\le10^{12} 1≤T≤105,1≤n≤105,1≤di≤1012
并且保证 ( ∑ n ∈ o n e t e x t c a s e n ) ≤ 1 0 5 (\sum_{n\in\ \text one\ \text text\ \text case} n ) \le\ 10^5 (∑n∈ one text casen)≤ 105
Solution
一般这种有 n n n 个的数组, n n n 会很大,求一种 v a l u e \tt value value 什么的,一定是一种规律性的问题。
所以我们一般从两个数开始,从特殊到一般,一般简单推一下就能找到拓展到 n n n 个数的答案。
我们首先分析两个的情况。
我们假设两个正整数 a , b a,b a,b
那么序列就会有四个数: a , b , − a , − b a,b,-a,-b a,b,−a,−b
d 1 = ∣ a − a ∣ + ∣ a − b ∣ + ∣ a − ( − a ) ∣ + ∣ a − ( − b ) ∣ d_1=|a-a|+|a-b|+|a-(-a)|+|a-(-b)| d
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。