PTA美丽数列

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循环,对循环变量的加减应该放到循环体的最后
原文地址:https://www.cnblogs.com/BeautifulWater/p/14521918.html