牛客练习赛16 B.漂亮的树(思维)


       题目链接:https://www.nowcoder.com/acm/contest/84/B

       这道题我第一次写的时候,我的想法是正着去模拟遍历最小的变动次数,最后没写出来,好像这个思路不太对。正确的方法是反向去思考,我们先得到一个初始化为题目要求的pre数组,为了解释的清楚一点(这里描述的和代码不太一样),在ans数组里输入n个数,然后我们需要求出对应的第i个数的ans[i] - pre[i]的差值的个数,然后求出这些差值的最大值,就表示不需要变动的值的个数,然后用n减去这个最大值就是最小需要变化的个数。


AC代码:

#include 
#include 
#include 
using namespace std;
int pre[100005];
int ans[250005];
int n;

int main()
{
  scanf("%d",&n);
  int t = n / 2;
  if(n % 2)t++;
  for(int i=1;i<=t;i++){
    pre[i] = pre[n-i+1] = i;
  }
  int sum = -1;
  int x;
  memset(ans,0,sizeof(ans));
  for(int i=1;i<=n;i++){
    scanf("%d",&x);
    int p = pre[i] - x;
    ans[p + 100000]++;      // 加100000是为了防止负值的出现
  }
  for(int i=0;i<=200005;i++){
    sum = max(sum,ans[i]);
  }
  printf("%d\n",n - sum);
  return 0;
}

你可能感兴趣的:(补题补题补题)