幸运数--打表

Description

世界上有很多人都有不同的习惯。
比如,13"这个数字被西方的一些国家和民族视为不吉利的凶数。4这个数字被很多亚洲人认为是不吉利的数。
北方的小红红就不太喜欢“7”这个数字,她认为如果一个正整数能被7整除,或者这个数的某一位有7,这个数就不是一个吉利的数。比如71,十位上有7这个数字,所以71是不吉利数字。再比如14能被7整除,14也不是吉利数字。现在问题来了,小红红想知道小于N的所有吉利数的平方和,你能帮助小红红解决这个问题吗?

例如:N = 8,<= 8与7无关的数包括:1 2 3 4 5 6 8,平方和为:1+4+9+16+25+36+64=155。

Input

输入:
第一行:输入一个N,代表输入的测试样例的个数。
接下来的2-N+1行,每行有一个M。
1<=N<1001,1 <= M< 10^6+1

Output

输出:
共N行,每行一个数,对应N个测试的计算结果。

Sample Input 1

4
4
2
1
6

Sample Output 1

30
5
1
91

Hint

注意时间复杂度!

/*
 * 2018-01-15
 * 数据量很大,直接处理肯定超时,借鉴素数筛选法的思想提前打表再直接输出即可
 * 处理的方式就是对每一个数进行模拟,依次去掉不符合条件的数,
 * 然后利用数组进行前缀求和
 * */
import java.util.*;
public class Main {
    static Scanner in = new Scanner(System.in);
    static int maxn = 1000000+5;
    static boolean[] vis = new boolean[maxn];
    static long[]  sum = new long[maxn];
    static void init() {
    	Arrays.fill(vis, true);
    	for(int i = 7;i < maxn ;i+=7) //去掉7的倍数
    		 vis[i]=false;
    	for(int i = 1;i < maxn ;i*=10) {//依次剔除个位,十位,百位。。。。
    		int temp = i*10;
    	  for(int j = i*7;j < maxn ;j+=temp) {//剔除所有为这个位的,比如17,27,37。。。。。。
    			for(int k = 0;k < i;k++) {
    				vis[j+k] = false;//剔除所有在这个位的下面的,比如71,72,73。。。。79.
    			}
    		}
    	}
    	sum[0] = 0;
    	//递推求解前缀和
    	for(int i = 1;i < maxn ;i++) {
    		if(vis[i])
    			sum[i]=sum[i-1]+i*i;
    		else
    			sum[i]=sum[i-1];
    	}
    	
    }
	public static void main(String[] args) {    
       int n = in.nextInt();
       init();
       while(n-->0) {
    	   int m = in.nextInt();
    	   System.out.println(sum[m]);
       }
	}
}

这里贴上我的另一种,我觉得思路还是蛮巧妙的。

import java.util.*;
public class Main {
    static Scanner in = new Scanner(System.in);
    static int maxn = 1000000+5;  
    static boolean[] vis = new boolean[maxn];  
    static long[]  sum = new long[maxn]; 
    static void init() {
     Arrays.fill(vis, true);
     sum[0] = 0;
     String s ;
     for(int i = 1;i< maxn;i++) {
      if(i%7==0) {
        vis[i] = false;//7的倍数过滤
      }else {
          s = String.valueOf(i);
          int len = (int) Math.pow(10, s.length()-1);
          int first = i/len;//第一位为7
          if(first==7)
           vis[i] = false;
          if(i%10==7)//最后一位为7
             vis[i] = false;
          String[] ss= s.split("7");//根据7拆分,长度等于0证明全部为7,长度大于一证明一定有7
          Arrays.fill(ss, "");
          if(ss.length==0||ss.length>1)
           vis[i] = false;            
      }
      if(vis[i])//地推求和
       sum[i] = sum[i-1] + i*i;
      else
       sum[i] = sum[i-1];
     }
     
    }
 public static void main(String[] args) {
     int n = in.nextInt();
     init();
     while(n-->0) {
      int m = in.nextInt();
      System.out.println(sum[m]);
     }
 }
}
		   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值