目录
题目:
几次失败的尝试:
“40分”代码:
import java.util.Scanner;
public class PREV_284 {
//杨辉三角问题
public static void main(String[] args) {
int n=2000;//杨辉三角层数 n的取值太大会报错 根据系统检测范围确定n的取值
Scanner scanner = new Scanner(System.in);
int N=scanner.nextInt();//输入被查找的数字
tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号
}
}
class tools_PREV_284 {
//生成杨辉三角
public long YH_trangle_production(int n,int N){
int x=0;
long a[][]=new long[n][];
long b[]=new long[(1+n)*n/2];
long index=-1;//索引
for (int i = 0; i < n; i++) {
//第二维不等长 第一行一列 第二行二列......
a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
//每行首尾均为1
a[i][0]=1;
a[i][i]=1;
//起止位置:第2--倒数第2
for (int j = 1; j < a[i].length-1; j++) {
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
//赋值
b[x]=a[i][j];
x++;
}
}
//查找指定数字的序号 b[]
for (int i = 0; i < b.length; i++) {
if (N==b[i]){
index=i+1;
break;
}
}
//如果在数组中没有找到 那么这个数d
if (index==-1){
index=((N+1)*N)/2+2;
}
return index;
}
}
第一次尝试遇到的问题:
1、确定杨辉三角层数:n
由于数组不可能存放太大数量的元素,所以不可能在数组b中存放过多杨辉三角数字。
在网上看到有的博主分析到:1900层是突破口(所以我把我的层数设置成了2000层)。
N如果在2000层内都没有出现过,那么N必定在第i层的第2个或者第3个。
2、代码太啰嗦
3、死脑筋,除了数组或许可以尝试利用集合arraylisy
“50分”代码:
import java.util.Scanner;
public class PREV_284 {
//杨辉三角问题
public static void main(String[] args) {
int n=2000;//杨辉三角层数 n的取值太大会报错 根据系统检测范围确定n的取值
Scanner scanner = new Scanner(System.in);
int N=scanner.nextInt();//输入被查找的数字
tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号
}
}
class tools_PREV_284 {
//生成杨辉三角
public long YH_trangle_production(int n,int N){
int x=0;
long a[][]=new long[n][];
long b[]=new long[(1+n)*n/2];
long index=-1;//索引
int the_num_rows=2001;//
boolean flag=true;
for (int i = 0; i < n; i++) {
//第二维不等长 第一行一列 第二行二列......
a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
//每行首尾均为1
a[i][0]=1;
a[i][i]=1;
//起止位置:第2--倒数第2
for (int j = 1; j < a[i].length-1; j++) {
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
//赋值
b[x]=a[i][j];
x++;
}
}
//查找指定数字的序号 b[]
for (int i = 0; i < b.length; i++) {
if (N==b[i]){
index=i+1;
break;
}
}
if (index!=-1){
return index;//目标在数组b内 则返回对应位置
}
//所找数字不在数组b内时(待优化 一个个算太费时间)
else{//目标不在数组内 则按照公式返回
while(flag){
if (N==the_num_rows){
flag=false;
//return the_num_rows*(1+the_num_rows)/2+2;
index=the_num_rows*(1+the_num_rows)/2+2;
}
if (N==the_num_rows*(the_num_rows-1)/2){
flag=false;
//return the_num_rows*(1+the_num_rows)/2+3;
index=the_num_rows*(1+the_num_rows)/2+3;
}
the_num_rows++;
}
return index;
}
}
}
第二次尝试遇到的问题:
我的测试输出结果与系统测试输出不一样 我不知道为什么!
再次修改代码(50分):
import java.util.Scanner;
public class PREV_284 {
//杨辉三角问题
public static void main(String[] args) {
int n=1900;//杨辉三角层数 n的取值太大会报错 根据系统检测范围确定n的取值
Scanner scanner = new Scanner(System.in);
int N=scanner.nextInt();//输入被查找的数字
tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号
}
}
class tools_PREV_284 {
//生成杨辉三角
public long YH_trangle_production(int n, int N){
int x=0;
long a[][]=new long[n][];
long b[]=new long[(1+n)*n/2];
long index=-1;//索引
//int the_num_rows=1900;//
boolean flag=true;
int rows=0;
for (int i = 0; i < n; i++) {
//第二维不等长 第一行一列 第二行二列......
a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
//每行首尾均为1
a[i][0]=1;
a[i][i]=1;
//起止位置:第2--倒数第2
for (int j = 1; j < a[i].length-1; j++) {
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
//赋值
b[x]=a[i][j];
x++;
}
}
//查找指定数字的序号 b[]
for (int i = 0; i < b.length; i++) {
if (N==b[i]){
index=i+1;///
break;
}
}
if (index==-1){
rows=(int)(Math.sqrt(N));
while(rows*(rows-1)/2<N){
if (N==rows*(rows-1)/2){
index=rows*(rows+1)/2+3;/
break;
}
rows++;
}
if (index==-1){
rows=N;
index=rows*(rows+1)/2+2;
}
}
return index;
}
}
不知道哪里出了问题 继续修改。。。。。。
破案了!是因为数据类型的问题导致出错long转化int数值溢出
满分代码:
100分代码:
import java.util.Scanner;
public class PREV_284 {
//杨辉三角问题
public static void main(String[] args) {
int n=1901;//杨辉三角层数 n的取值太大会报错 根据系统检测范围确定n的取值
Scanner scanner = new Scanner(System.in);
int N=scanner.nextInt();//输入被查找的数字
tools_PREV_284 mytools_prev_284 = new tools_PREV_284();
System.out.println(mytools_prev_284.YH_trangle_production(n,N));//输出被查找数字第一次出现的序号
}
}
class tools_PREV_284 {
//生成杨辉三角
public long YH_trangle_production(int n, int N){
int x=0;
long a[][]=new long[n][];
long b[]=new long[(1+n)*n/2];
long index=-1;//索引
//int the_num_rows=1900;//
boolean flag=true;
long rows=0;
for (int i = 0; i < n; i++) {
//第二维不等长 第一行一列 第二行二列......
a[i]=new long [i+1];//必须规定每行数组的列数 否则报错
//每行首尾均为1
a[i][0]=1;
a[i][i]=1;
//起止位置:第2--倒数第2
for (int j = 1; j < a[i].length-1; j++) {
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
//赋值
b[x]=a[i][j];
x++;
}
}
//查找指定数字的序号 b[]
//经过测试:第0层到第1900层出现过的数字 都能准确的返回对应序号
for (int i = 0; i < b.length; i++) {
if (N==b[i]){
index=i+1;
break;
}
}
//现在考虑
if (index==-1){
rows=(int)(Math.sqrt(2*N));
while(rows*(rows-1)/2<N){
rows=rows+1;
if (rows*(rows-1)/2==N){
index=rows*(rows+1)/2+3;
break;
}
index=-2;
}
if (index==-2){
rows=N;
index=rows*(rows+1)/2+2;
}
}
return index;
}
}
对我来说,上面这段代码修改的关键是:将rows的类型由int改为long 然后就出来了
总结:
1、找规律
不可能将所有数据储存在数组里,经过分析(见参考博文)发现大约在1900行之后,目标数字N只可能出现在某行的第2或者第3的位置
2、