• 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循环,对循环变量的加减应该放到循环体的最后
  • 相关阅读:
    第六十三篇 用户权限、pymysql模块
    第六十二篇 视图、触发器、事务、存储过程
    第六十一篇 SQL查询语句
    第六十篇 约束、表关系
    第五十九篇 数据库配置文件以及数据类型
    第五十八篇 epoll模型、数据库
    第五十七篇 IO模型
    第五十六篇 并发之协程
    第五十五篇 死锁、GIL锁以及Pool
    第五十四篇 并发之线程
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/14521918.html
Copyright © 2020-2023  润新知