test 2019-11-01

test 2019-11-01   蒟蒻一枚,弱弱总结——

T1:Dove 下跳棋

问题描述:

  Dove 喜爱下跳棋,在传统的跳棋基础之上,Dove 又延伸出了许多别的玩法。Dove 以一个一维数轴为棋盘下跳棋,总共会移动棋子 𝑛 − 1 次。因为讨厌没有规律,所以 Dove 每次只会恰好把棋子向右移动 𝑘 个格子。

  Cicada 送给了 Dove 一个长度为 𝑛 的数列 {𝑎},为了表示感谢,Dove 打算以 Cicada
送给他的序列 {𝑎} 为基础下跳棋。具体的,Dove 将会把棋子从编号为 𝑎1 的格子出发,在第
𝑖 次移动后,把棋子移动到编号为 𝑎𝑖+1 的格子。显然 Cicada 送给他的 {𝑎} 有可能不满足
Dove 要求的条件,Dove 想知道,最少需要修改多少个 𝑎𝑖 的值,才能使得这个数列 {𝑎} 是
满足 Dove 需要的移动棋子的要求的。

输入:
  第一行输入两个整数 𝑛, 𝑘。接下来一行输入 𝑛 个整数表示 {𝑎},第 𝑖 个数为 𝑎𝑖。

输出:
  输出一行一个整数,表示最少需要修改的值的数量。

  样例 :

  chess1.in

    18 -3
    78260 -82654 -11527 -83872 -4432 50471 96185 34310 25899 32430 4718 81502     23660 82676 2172 -36826 -64408 -49929

    chess1.out

    17

  约定和数据范围:

    对于全部测试点,保证 2 ≤ 𝑛 ≤ 105, |𝑎𝑖|, |k| ≤ 105

    

测试点 n k
1,2,3 ≤ 300 0 ≤ k ≤ 3000
4,5,6 ≤ 300  
7,8   0 ≤ k
9,10    

分析:

  算法一:

  显然,无论修改多少个位置的数,我们至少需要保留一个位置上的数,全部修改一定不是最优的。如果我们能够确定一个位置 i 是不修改的,那么对于第 j 个位置,我们就能够确定其应该具有的权值应为 ai + (j − i) × k,否则就为要修改的数。

  时间复杂度为 O(n2)……

  这种算法是可以直接想到的,但时间复杂度太高,有点尴尬,放弃……

  算法二:

  观察到对于每个位置上的数来说,如果它是不需要修改的。那么他能唯一确定第一个位置上的数。如果我们能够确定一个位置 i 是不修改的,那么对于第 j 个位置,我们就能够确定其应该具有的权值应为 ai + (j − i) × k,根据权值我们再比较一下就得出答案……

  时间复杂度为 O(n)……

代码:

  

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 inline long long read() {
 5     long long number = 0, symbol = 1;
 6     char ch = getchar();
 7     while ('0' > ch || ch > '9') {
 8         if (ch == '-')
 9             symbol = -1;
10         ch = getchar();
11     }
12     while ('0' <= ch && ch <= '9') {
13         number = (number << 3) + (number << 1) + (ch ^ 48);
14         ch = getchar();
15     }
16     return number * symbol;
17 }
18 
19 const int maxn = 100000 + 10;
20 long long n, k, a[maxn], cnt, ans;
21 
22 int main() {
23     freopen("chess.in", "r", stdin);
24     freopen("chess.out", "w", stdout);
25     n = read();
26     k = read();
27     for (int i = 1; i <= n; i++) {
28         a[i] = read();
29         a[i] = a[i] - ((i - 1) * k);
30     }
31     a[0] = -0x3f3f3f3f;
32     for (int i = 1; i <= n; i++) {
33         if (a[i] != a[i - 1])
34             cnt = 1;
35         else
36             cnt++;
37         ans = max(ans, cnt);
38     }
39     printf("%lld\n",n - ans);
40     return 0;
41 }
View Code

 

posted @ 2019-11-03 15:07  Z_MIKI  阅读(237)  评论(0)    收藏  举报