引入
比如我们要求某数组中的每个数字的质数因子,比如 9 = 3 ∗ 3 9=3*3 9=3∗3,但数组中给的数是范围是1-1000
我们可以设置一个求出1-1000的质数的表(放在静态区),每个用例直接用这个表就行。
打表找规律
例题1:
小虎买苹果,他有装8个苹果的袋子和装6个苹果的袋子,要求袋子最少,且用的袋子都满了。
暴力法先把结果打出来,尽可能用8号袋装,然后看剩余结果能否用6号袋装,不行,就把8号袋减去一个,再看能不能用6号袋装…把每个值打印出来,找规律。
public class abc {
static int mink;
//tested
public static boolean issix(int num)
{
if(num%6==0)
return true;
else
return false;
}
public static int buyapples(int apples)
{
if(apples==0)
return -1;
System.out.print(apples+":");
int n=apples/8;
while(n!=-1&&!issix(apples-n*8))
{
n-=1;
}
if(n==-1)
return -1;
return n+(apples-n*8)/6;
}
//把1-100的苹果打印出来
public static void main(String[] args) {
for(int i=0;i<100;i++)
{
System.out.print(buyapples(i));
System.out.println();
}
}
}
找规律!!
- 0返回-1
- 奇数返回-1
- 会发现从3以后,每个数字都对应4个apples的数量,且最后一个对应的apples数量就是8*i
O(1)完美解决该题,程序中试了全都一样。数学原理是满8的递减2(不太重要),
public static int buyapples2(int apples)
{
if(apples==6||apples==8)
return 1;
if(apples==12|apples==14||apples==16)
return 2;
if(apples<=13)
return -1;
if(apples==0||apples%2==1)
return -1;
if(apples%8==0)
return apples/8;
else
return apples/8+1;
}
例题2:
给定一个正整数N,表示有N份青草统一堆放在仓库里
有一只牛和一只羊,牛先吃,羊后吃,它俩轮流吃草
不管是牛还是羊,每一轮能吃的草量必须是:
1,4,16,64…(4的某次方)
谁最先把草吃完,谁获胜
假设牛和羊都绝顶聪明,都想赢,都会做出理性的决定
根据唯一的参数N,返回谁会赢
eg分析:
草为1的时候,先手选1,先手赢
草为2的时候,先手选1,后手选1,后手赢
草为3的时候,先手选1,后手选1,先手选1,先手赢
草为4的时候,先手选4,先手赢
草为5的时候,先手选4,后手选1,后手赢;或者先手选1,后手选4,后手赢。
草为6的时候,先手选1,后手选4,先手选1,先手赢;或者先手选4,后手选1,先手赢。
看到这里,基本可以确定,草的数目后确定后,对应唯一的结果,这也是“绝顶聪明”的意思,因此我们可以着手写暴力法。
从6开始 会发现 “先后先先后” 的规律 改写成O(1)
public static String whowin2(int grass)
{
if(grass<5)
{
if(grass%2==0)
return"后手";
if(grass%2==1)
return"先手";
}
int n=grass%5;
if(n==1||n==3||n==4)
return "先手";
else
return "后手";
}
例题3:
定义一种数:可以表示成若干(数量>1)连续正数和的数
比如:
5 = 2+3,5就是这样的数
12 = 3+4+5,12就是这样的数
1不是这样的数,因为要求数量大于1个、连续正数和
2 = 1 + 1,2也不是,因为等号右边不是连续正数
给定一个参数N,返回是不是可以表示成若干连续正数和的数。
先手暴力解:
public static boolean isthenum(int num)
{
for(int i=1;i<num;i++)
{
int sum=i;
int j=i+1;
while(true)
{
sum+=j;
if(sum==num)
return true;
else if(sum>num)
break;
j+=1;
}
}
return false;
}
public static void main(String[] args) {
for(int i=1;i<=100;i++)
{
System.out.print(i+": ");
System.out.print(isthenum(i)+" ");
if(i%10==0)
System.out.println();
}
}
会发现:false很少:有1 ,2,4,8,16,32,64…2^n
//tested
//检测n是否是2的次方
public static boolean islog2ed(int n)
{
double l=n;
double q=Math.log(l)/Math.log(2);
if(q==(int)q)
{
return true;
}
return false;
}
public static boolean isthenum2(int num)
{
if(islog2ed(num))
return true;
return false;
}