PTA美丽数列
小明是个普通的计算机本科生,很喜欢研究数列相关的问题。在他的认知里,美丽的数列是这样的,对于一个长度为n的数列a,存在一个下标i(1<=i<=n)使得1i之间的数是严格递增的,i+1n之间的数是严格递减的。现在这个数列a里的元素是随机给定的(这个数列可能是不美丽的),对于数列a内的任意一个元素ai我们可以进行若干次ai=ai-1(ai>0)的操作,问能否通过若干次操作使得这个数列变得美丽。
输入格式:
第一行输入数列长度n (1≤n≤3*1e5), 第二行输入n个整数a1,…,an (0≤ai≤1e9)。
输出格式:
输出“Yes”表示这个数组可以变美丽,输出“No”表示不可以。
输入样例:
3
1 0 1
输出样例:
No
解题思路:
错误但PTA过关
- 贪心的思想:直接找到最大的,然后往两边走
错误代码,但过关
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
int pos=0;
int h,l,r;
int n;
cin>>n;
int a[n+1];
cin>>a[pos];
for(int i=1;i<n;i++)
{
cin>>a[i];
if(a[i]>a[pos])
pos=i;
}
l=pos-1;
r=pos+1;
h=a[pos];
while(l>=0)
{
if(h>a[l])
{
h=a[l];
}
else
{
h=h-1;
if(h<0)
{
cout<<"No";
return 0;
}
}
l--;
}
h=a[pos];
while(r<n)
{
if(h>a[r])
{
h=a[r];
}
else
{
h=h-1;
if(h<0)
{
cout<<"No";
return 0;
}
}
r++;
}
cout<<"Yes";
return 0;
}
hack数据
6
5 2 4 3 2 1
正确的思路
-
特判:如果说读入的数组的最大值小于数组长度,直接输出No
-
从左到右,每个点都作为中心点
-
以中心点为起始端,分两侧去扫描和加以判断。
-
判断:
拿向左走为一个例子,若新走到的点小于原来的点,则保持新走到的点的值不变,否则,将其更新为原来的点的值的-1;
-
while(left>=0) { if(t[left]>=t[left+1]) { t[left]=t[left+1]-1; } if(t[left]<0) { flag=0; break; } left--; }
正确的代码
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
int n;
cin>>n;
int a[n+1];
int maxa=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
maxa=maxa>a[i]?maxa:a[i];
}
if(maxa<n)
{
cout<<"No";
return 0;
}
int t[n+1];
int flag;
for(int i=0;i<n;i++)
{
flag=1;
for(int j=0;j<n;j++)
t[j]=a[j];
int center=i;
int left=center-1;
int right=center+1;
while(left>=0)
{
if(t[left]>=t[left+1])
{
t[left]=t[left+1]-1;
}
if(t[left]<0)
{
flag=0;
break;
}
left--;
}
if(!flag)continue;
while(right<n)
{
if(t[right]>=t[right-1])
{
t[right]=t[right-1]-1;
}
if(t[right]<0)
{
flag=0;
break;
}
right++;
}
if(flag)
{
break;
}
}
if(flag)
cout<<"Yes";
else
cout<<"No";
return 0;
}
其他
其他思路
从左走1234。。填到不能再填,从右往左走1234.。。填到不能再填。。若最终区域有交叉,则美丽数列可以存在。(khgg)
编码习惯纠正
- while循环,对循环变量的加减应该放到循环体的最后