• Project Euler 44 Sub-string divisibility( 二分 )



    题意:五边形数由公式Pn=n(3n−1)/2生成,在所有和差均为五边形数的五边形数对Pj和Pk中,找出使D = |Pk − Pj|最小的一对;此时D的值是多少?

    思路:二分找和差


    /*************************************************************************
        > File Name: euler044.c
        > Author:    WArobot 
        > Blog:      http://www.cnblogs.com/WArobot/ 
        > Created Time: 2017年06月27日 星期二 10时59分39秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <inttypes.h>
    
    #define MAX_N 5000
    #define MAX_RANGE 37497500
    
    bool Binary_Serch(int32_t n , int32_t *p) {			// 判断n是否在数组num[]中
    	if (n > MAX_RANGE)	return false;
    	int32_t l = 1 , r = MAX_N - 1 , mid;
    	while (l < r) {
    		mid = (l + r) >> 1;
    		if (p[mid] < n)		l = mid + 1;
    		else				r = mid;
    	}
    	return p[r] == n;
    }
    
    int32_t main() {
    	int32_t p[MAX_N];
    	for (int32_t i = 1 ; i < MAX_N ; i++) {
    		p[i] = ( 3 * i * i - i ) / 2;
    	}
    	int32_t ans = MAX_RANGE + 10;
    	bool flag = false;
    	for (int32_t k = 1 ; k < MAX_N ; k++) {			// p[k] > p[j] k 从小到大枚举 j 从大到小枚举 
    		for (int32_t j = k - 1 ; j >= 1 ; j--) {
    			if (!Binary_Serch(p[k] + p[j] , p))	continue;
    			if (!Binary_Serch(p[k] - p[j] , p)) continue;
    			if (ans > p[k] - p[j]) {				// 假如 ans已经被 p[k] - p[j] 更新完成那就没必要向下继续枚举j,因为向下枚举j时D肯定不会被更新
    				ans = p[k] - p[j];	flag = true;
    				break;
    			}
    		}
    		if (flag)	break;							// 如果 ans已经被更小的 p[k] - p[j] 更新过一次,那就没有必要继续枚举k了,因为向上继续枚举k并不会让D更小
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    方法二:

    /*************************************************************************
    	> File Name: test.cpp
    	> Author: 
    	> Mail: 
    	> Created Time: 2018年02月03日 星期六 08时42分28秒
     ************************************************************************/
    
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    ll Pentagonal(ll n) {
        return n * (n * 3 - 1) / 2;
    }
    bool isPentagonal(ll n) {
        int l = 1, r = n, mid;
        while (l <= r) {
            mid = (l + r) >> 1;
            ll t = Pentagonal(mid);
            if (t == n) {
                return true;
            } else if (t < n) {
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return false;
    }
    
    int main() {
        ll ans = INT_MAX;
        ll n = 1, m, p1, p2;
        while (true) {
            p1 = Pentagonal(n);
            p2 = Pentagonal(n - 1);
            if (p1 - p2 > ans) break;
            for (int m = n - 1 ; m >= 1 ; --m) {
                p2 = Pentagonal(m);
                if (p1 - p2 >= ans) break;
                if (isPentagonal(p1 + p2) && isPentagonal(p1 - p2)) {
                    ans = p1 - p2;
                }
            }
            ++n;
        }
        printf("ans is %lld
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    vuex 命名空间
    vue-touchjs
    Jackson最简单用法
    Bootstrap登录样式
    Left/Right/Inner Join用法和区别
    VS2015安装提示出现“安装包丢失或损坏”解决方法
    HTML之禁止输入文本
    jQuery之call()方法的使用
    jQuery操作cookie
    jQuery常用的查找Dom元素方法
  • 原文地址:https://www.cnblogs.com/WArobot/p/7084340.html
Copyright © 2020-2023  润新知