题目
时间限制: 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]
这种情况需要把 tail 和 tail−1 合并,修改 tail 。 -
A[head]<A[tail]
这种情况合并 head 和 head+1 ,修改 head 。 -
A[head]=A[tail]
不需要合并,直接修改 tail 和 head 。
代码
代码没什么好说的。
#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 1000000
int 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);
}