编程题赏析2

1:牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等。问是否可行。
牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍。
这个操作的使用次数不限,也可以不使用,并且可以对同一个位置使用多次。

输入描述:
输入一个正整数N (N <= 50)
接下来一行输入N个正整数,每个数均小于等于1e9.

输出描述:
假如经过若干次操作可以使得N个数都相等,那么输出"YES", 否则输出"NO"

输入例子:
2
1 2
输出例子:
YES           
package com.itheima.niuke.com;

import java.util.Scanner;

public class Test7 {

	public static void main(String[] args) {
	
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
        int n=sc.nextInt();
        int[] a=new int[n];
        String result="YES";
       for(int i=0;i<a.length;i++)
       {
    	   a[i]=sc.nextInt(); 
       }
		for(int i=0;i<a.length;i++)
		{
			while(a[i]%2==0)
			{
				a[i]=a[i]/2;
			}
			
		}
       for(int i=1;i<a.length;i++)
       {
    	   if(a[i]!=a[0])
    	   {
    		   result="NO";
    		   break;
    	   }
       }
 
     System.out.println(result);  
	}
	}
}:
 
2:牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。 
输入描述:
输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;
第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。
输出描述:
输出一个整数,表示最长的长度。
输入例子:
6 
7 2 3 1 5 6
输出例子:
5
分析:这道题目看上去没法下手,就当学习一个思路吧,首先根据当前数组顺着求一遍以每个位置作为结尾的连续最长递增子序列的长度值,再逆着求解以每个元素作为开头的连续最长递增子序列的长度值,然后根据这两组值来找连接点。具体就拿体重的例子来说,此时数组arr为 7 2 3 1 5 6,我们定义两个数组left 和right,left数组表示正着求以每个元素作为结尾的最长递增子序列的长度,而right数组表示逆着以每个元素作为开头的连续最长递增子序列的长度值,所以可以知道left[0]=1,表示以7结尾的目前最长的连续递增子序列的长度值就是1,依次left[1]=1,left[2]=2,left[3]=1,left[4]=2,left[5]=3; 而right[5]=1,right[4]=2,right[3]=3,right[2]=1,right[1]=2,right[0]=1;好了,到此为止两个辅助的数组已经求出,接下来就要找连接点了,是这样的,根据题目意思,我们要找一个子序列,而且之多改变一个数就可以形成严格的连续递增子序列,所以我们先盯住数组中2这个数,我们发现以7结尾的最长的连续递增子序列的长度为left[0],而以3开头的连续递增子序列长度为right[2],这样,我们其实不用管7和3之间的数到底是多少,是2也好,不是2也好,只要2前面的数7能够严格小于2后面的数3,说明通过改变7和3之间这个数至合适的数值则,这两部分就可以连成一个连续的严格递增子序列,所有,我们遍历所有这样的点,记录满足条件的最大的长度再加1即可。
   
package com.itheima.niuke.com;
/*
 * 牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。 
输入描述:
输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;
第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。
输出描述:
输出一个整数,表示最长的长度。
输入例子:
6 
7 2 3 1 5 6
输出例子:
5
 * 
 */
import java.util.Arrays;
import java.util.Scanner;
 
public class Test8 {
 
    public static void main(String[] args) {
 
        Scanner in = new Scanner(System.in);
        int n = Integer.parseInt(in.nextLine());
         
        String[] cmd = in.nextLine().split(" ");
        int[] arr = new int[n];
        for (int i = 0; i < arr.length; i++)
            arr[i] = Integer.parseInt(cmd[i]);
 
        System.out.println(longestSubSeq(arr));
    }
     
    public static int longestSubSeq(int[] arr) {
        int[] left = new int[arr.length];
        int[] right = new int[arr.length];
        left[0]=1;
        for (int i = 1; i < arr.length; i++) {
            if(arr[i] > arr[i-1])
                left[i] = left[i-1]+1;
            else
                left[i] = 1;
             
        }
        right[arr.length-1] = 1;
        for (int i = right.length-2; i >=0 ; i--) {
            if(arr[i] < arr[i+1])
                right[i] = right[i+1]+1;
            else
                right[i] = 1;
        }
//      System.out.println(Arrays.toString(left));
//      System.out.println(Arrays.toString(right));
        int max = 0;
//        if(right[0] > max)
//            max = right[0];
        for (int i = 1; i < arr.length-1; i++) {
            int a = left[i-1];
            int b = right[i+1];
            if(arr[i-1] < arr[i+1] && a+b > max)
                max = a+b;
        }
//        if(left[arr.length-1] > max)
//            max = left[arr.length-1];
        return max+1;
    }
 
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值