NOIP普及组模拟★回文数组

来源:互联网 发布:电脑护眼知乎 编辑:程序博客网 时间:2024/05/16 08:01

题目

时间限制: 1 Sec 内存限制: 128 MB

题目描述

给定有N个整数的数组A,下标从1到N。如果对每一个下标i均满足A[i] =A[N-i+1],则称数组是回文的。
例如,数组A={1,2,3,2,1}就是回文数组。
如果数组A不是回文的,可以采用合并两个相邻元素的方法去得到回文数组。注意,每操作一次,数组的元素数量减少1。
例如,数组A={1,2,3}不是回文数组,但是通过合并A[1]和A[2],得到{3,3}就是回文数组了。
显然,无论给出怎样的数组元素,最多经过N-1次操作,合并为一个数时,数组A一定是回文数组了。因此,本题一定有解。
然而问题来了:对于给定的数组A,最少经过多少次操作,能让A变成回文数组?

输入

第1行:1个整数N,表示数组A的元素个数
第2行:N个空格分开的整数,表示数组A
1 <= N <= 10^6
1 <= A[i] <= 10^9

输出

第1行:1个整数,表示最少的操作次数

样例输入

4
1 4 3 2

样例输出

2

思路

本来很水的一道题,而且考试时思路与正解沾了点边,最后写着写着就写成了暴力[手动笑哭]。

想想回文数组要满足的条件:首尾相等。而我们要处理的数组中,如果首尾不相等,显然就需要更改。
分三种情况:

  • A[head]>A[tail]
    这种情况需要把tailtail1合并,修改tail
  • A[head]<A[tail]
    这种情况合并headhead+1,修改head
  • A[head]=A[tail]
    不需要合并,直接修改tailhead

代码

代码没什么好说的。

#include<cstdio>int read(){    int x=0,f=1;char s=getchar();    while(s<'0'||s>'9'){if(x=='-')f=-1;s=getchar();}    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}    return x*f;}#define MAXN 1000000int N;int A[MAXN+5];int main(){    N=read();    for(int i=1;i<=N;i++)        A[i]=read();    int head=1,tail=N,ans=0;    while(head<tail)    {        if(A[head]!=A[tail])        {            ans++;            if(A[head]>A[tail]) A[tail-1]+=A[tail--];            else A[head+1]+=A[head++];        }        else head++,tail--;    }    printf("%d",ans);}
原创粉丝点击