• 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;
    }
    
  • 相关阅读:
    169. Majority Element
    283. Move Zeroes
    1331. Rank Transform of an Array
    566. Reshape the Matrix
    985. Sum of Even Numbers After Queries
    1185. Day of the Week
    867. Transpose Matrix
    1217. Play with Chips
    766. Toeplitz Matrix
    1413. Minimum Value to Get Positive Step by Step Sum
  • 原文地址:https://www.cnblogs.com/WArobot/p/7084340.html
Copyright © 2020-2023  润新知