九月的彩笔
Color
【题目描述】
九月的桌面上有一行调色板,上面有n个格子,每个格子都涂上了k种颜色中的其中一种,颜色用’A’到’Z’编号。九月想给其中一些格子重新染色,使得没有相邻格子是同一种颜色,她想知道最少需要染多少个格子可以做到。
【输入描述】
第一行n,k
第二行一个字符串,为初始时的颜色
【输出描述】
一行为答案
【输入样例1】
6 3
ABBACC
【输出样例1】
2
【输入样例2】
3 2
BBB
【输出样例2】
1
【数据约定】
50%数据:n<=10000
100%数据:1<=n<=5*10^5,2<=k<=26
Solution
f[i,j] 表示算完前i个字母,第i个位j的需要重写的次数,然后 f[i−1] 中最小的和次小的搞一下就好。
特别行动队
Commando
【题目描述】
你有一支由 n 名预备役士兵组成的部队,士兵从1到n编号,要将他们拆分成若干特别行动队调入战场。出于默契的考虑,同一支特别行动队中队员的编号应该连续,即为形如(i, i + 1, …, i + k)的序列。
编号为 i 的士兵的初始战斗力为 xi ,一支特别行动队的初始战斗力 x为队内士兵初始战斗力之和,即 x = xi + xi+1 + … + xi+k。
通过长期的观察,你总结出一支特别行动队的初始战斗力 x将按如下经验公式修正为x’:x’ = ax^2 + bx + c,其中 a, b, c是已知的系数(a < 0)。
作为部队统帅,现在你要为这支部队进行编队,使得所有特别行动队修正后战斗力之和最大。试求出这个最大和。
例如, 你有4名士兵, x1 = 2, x2 = 2, x3 = 3, x4 = 4。经验公式中的参数为 a = –1, b = 10, c = –20。此时,最佳方案是将士兵组成 3个特别行动队:第一队包含士兵1和士兵2,第二队包含士兵3,第三队包含士兵 4。特别行动队的初始战斗力分别为4, 3, 4,修正后的战斗力分别为 4, 1, 4。修正后的战斗力和为 9,没有其它方案能使修正后的战斗力和更大。
【输入文件】
输入由三行组成。第一行包含一个整数 n,表示士兵的总数。第二行包含三个整数 a, b, c,经验公式中各项的系数。第三行包含 n 个用空格分隔的整数 x1, x2, …, xn,分别表示编号为1, 2, …, n的士兵的初始战斗力。
【输出文件】
输出一个整数,表示所有特别行动队修正后战斗力之和的最大值。
【输入样例】
4
-1 10 -20
2 2 3 4
【输出样例】
9
【数据范围】
20%的数据中,n ≤ 1000;
50%的数据中,n ≤ 10,000;
100%的数据中,1 ≤ n ≤ 1,000,000,–5 ≤ a ≤ –1,|b| ≤ 10,000,000,|c| ≤
10,000,000,1 ≤ xi ≤ 100。
Solution
暴力
O(n2)
20%。
决策单调乱搞
O(nlogn)
70%
斜率优化100%
拯救黑之王
String
【题目描述】
黑之王黑之睡莲遭遇了黄之王黄色电波的埋伏。黄之王发动技能进行幻术攻击,黑之王被困在里面了。作为黑之王最忠诚的属性,白银之鸦希望能解除掉黄之王的幻术。在白银之鸦面前出现了一个由01组成的字符串,破解黄之王幻术的秘诀就在于,找出这个字符串中正好含有k个1的子串的数量。令字符串S=s1s2s3…sn,那么S的子串定义为S_sub=si..j
【输入描述】
第一行k(0<=k<=10^6)
第二行为字符串S,长度小于等于10^6
【输出描述】
一行为答案
【输入样例】
2
01010
【输出样例】
4
【样例解释】
符合条件的子串为
0101 1010 101 01010
Solution
前缀和后统计-k的x,算前面前缀和为x有多少个统计即可。
最后的问题
And
【题目描述】
我能问你最后一个问题吗?
爱过。
不是这个问题!如果2个数按位and的结果为0,那么我们称这对数互为卡哇伊数,现在有n个数,我想找出每一个数在剩下n-1个数中的卡哇伊数。
【输入描述】
第一行n
第二行n个数,每个数<=4*10^6
【输出描述】
一行n个数,表示每一个数对应的卡哇伊数
【输入输出样例】
Input1
2
90 36
Output1
36 90
Input2
4
3 6 3 6
output2
-1 -1 -1 -1
Input3
5
10 6 9 8 2
output3
-1 8 2 2 8
【数据约定】
40%数据 n<=5000
100%数据 n<=10^6
Solution
其实我觉得开个Trie树就好了。。
然而还要写个dfs。。
而且时间复杂度好像不是很好的样子
not一下给定的数字,发现如果这个数的0为0,1为0或1的数字都是可行的。
Code
#include <cstdio>
const int N = (1 << 22) - 1;
int a[N + 5], f[N + 5];
int main() {
int n, i, j;
scanf("%d", &n);
for (i = 1; i <= n; ++i)
scanf("%d", &a[i]), f[a[i]] = a[i];
for (i = 0; i <= N; ++i) {
if (!f[i]) f[i] = -1;
for (j = i; j; j -= j & -j)
if (f[i - (j & -j)] > f[i])
f[i] = f[i - (j & -j)];
}
for (i = 1; i <= n; ++i)
printf("%d ", f[N ^ a[i]]);
return 0;
}