漂亮的树~思维题
链接:https://www.nowcoder.com/acm/contest/84/B
来源:牛客网
街上有n棵树,标号为1...n,第i棵树的高度为ai。
定义这n棵树是漂亮的,当且仅当
1. 对于所有的i,ai=an-i+1;
2. 对于1 <= i < n / 2 (不是整除),ai + 1= ai + 1;
比如说 “2 3 4 5 5 4 3 2”和“1 2 3 2 1”是漂亮的而“1 3 3 1”和“1 2 3 1”不是。
现在请问最少修改几棵树的高度(可以变大也可以变小),使得这些树是漂亮的。
定义这n棵树是漂亮的,当且仅当
1. 对于所有的i,ai=an-i+1;
2. 对于1 <= i < n / 2 (不是整除),ai + 1= ai + 1;
比如说 “2 3 4 5 5 4 3 2”和“1 2 3 2 1”是漂亮的而“1 3 3 1”和“1 2 3 1”不是。
现在请问最少修改几棵树的高度(可以变大也可以变小),使得这些树是漂亮的。
输入描述:
第一行一个整数n表示树的数量( 1 <= n <= 100,000)。
第二行n个整数表示树的高度( 1 <= a
i
<= 100,000)。
输出描述:
输出一个整数表示最少修改树的高度的数目。
示例1
输入
3 2 2 2
输出
1
示例2
输入
4 1 2 2 1
输出
0
好久没有做过思维题目了 。
感觉已经废了。
这题斜率是已知的。
通过斜率求解非常迅速,
注意一点数组下标为负数的情况。
所以我下标加了10W.
1 #include <cstdio> 2 #include <algorithm> 3 #include <vector> 4 #include <queue> 5 #include <cstring> 6 #include <string> 7 using namespace std; 8 const int maxn = 2e5 + 10; 9 int a[maxn], b[maxn]; 10 int main() { 11 int n; 12 while(scanf("%d", &n) != EOF) { 13 for (int i = 1 ; i <= n ; i++ ) 14 scanf("%d", &a[i]); 15 memset(b, 0, sizeof(b)); 16 for (int i = 1 ; i <= n ; i++) { 17 if (i <= n / 2) b[a[i] - i + 100000]++; 18 else b[a[i] - (n - i + 1) + 100000]++; 19 } 20 int ans = 0; 21 for (int i = 0 ; i < 200000 ; i++ ) { 22 ans = max(ans, b[i]); 23 } 24 printf("%d\n", n - ans); 25 } 26 return 0; 27 }