LevOJ P1719 Let's play a game!
作者:互联网
P1719 Let's play a game!
题目描述
现有一包含n 个数的序列A1,A2,A3,...,An,给定一个定值k.
每次我们可以选择数列中一个下标为 2 的次幂的元素(如A1,A2,A4,A8...) 将其删除出数列(删除后,其后的所有元素会自动前移一格)。
问最少进行多少次操作,能将序列中所有值为k 的元素删除?
输入描述
第一行两个整数n,k
第二行nn 个整数,A1,A2,...,An.
输出描述
第一行一个整数,为最少操作次数。
样例输入 1
5 2
1 2 4 2 5
样例输出 1
2
样例输入 2
5 2
1 2 2 2 2
样例输出 2
4
样例解释
对于样例11,依次删除A4,A2,即可。
对于样例22,连续删除4 次A2,即可。
数据规模与约定
1≤n≤3×10^5。
贪心做法,记录下每个指定值到自己前面的那个2的次方的距离,若在2的次方位置上,则可以直接删除,就是操作次数加1。
不在2的次方上的话,有2种情况,第一种,已经进行删除的操作数,大于删除该数所需的操作数,直接操作数加1即可,也就是直接删掉。怎么理解这种情况呢,我们可以这样想,当前面删除时,后面的数会向前移,因为要删除的操作数,大于删除该数所需的操作数,那么正好当该数移动到2的次方位置上时,我们对它进行删除。
第二种情况,已经进行删除的操作数,小于删除该数所需的操作数。我们取这个数所需的操作数。这个可以这样理解,当前面的数删除完成时,这个数已经快到能被删除的地方,那么再加上几次操作即可把这个数也删掉,这两次操作的数量加起来也就是要删除的这个数的操作数。
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 #define N 300004 5 int d[N]; 6 int distance(int n); 7 int main() 8 { 9 //把每个要删除的数字的位置记录下来 10 //并且计算出他们到自己前面的2的次方的距离 11 //找到距离非0的位置,看前面有几个距离为0,若数量大于自己的距离,直接删除,若小于,则要取最大 12 int n, k, j = 0, result = 0, t; 13 cin >> n >> k; 14 for (int i = 0; i < n; i++) 15 { 16 cin >> t; 17 if (t == k) 18 d[j++] = distance(i + 1); //记录每个值到最近的2的次方的距离 19 } 20 for (int i = 0; i < j; i++) //从左到右扫描指定值 21 { 22 if (!d[i] || d[i] < result) 23 result++; 24 else 25 result = max(result, d[i]); 26 } 27 cout << result << endl; 28 } 29 int distance(int n) 30 { 31 for (int i = 0; i < n; i++) 32 { 33 if (pow(2, i) == n) 34 return 0; 35 else if (pow(2, i) > n) 36 return n - pow(2, i - 1) + 1; 37 } 38 }
标签:play,删除,int,样例,操作数,Let,result,次方,P1719 来源: https://www.cnblogs.com/hh22/p/16295550.html