import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner input = new Scanner(System.in); int N = input.nextInt(); int ans = 1; int sqrtN = (int)Math.sqrt((double)N*2);//项数 < sqrt(2 * N) + 1 for(int i = 2;i < sqrtN + 1;i++){ if(i%2==1) { if (N % i == 0) ans++; //1. 当 项数 为奇数时,N % 项数 = 0 }else { if (N % i == i/2) ans++;//2. 当 项数 为偶数时,N % 项数 = 项数 / 2 } } System.out.println(ans); } }
public class Test{ /** * * 总体思路为根据求和公式,得到一个二次函数。求解二次函数判断当前位置是否满足条件 * 所以只需要一次遍历就可以搞定 * * 1:根据等比数列的求和公式得出 其中 * a1 表示数列第一个元素 * an 表示数列最后一个元素 * n表示数列的个数 并且 n = an - a1 + 1 * 最终求和公式为:(a1 + an)n / 2 = a * * 2:将 n 带入原公式 就可以得出如下表达式 (下面的 "^" 不是异或运算,表示乘方) * a 表示和,即传入的次数 * i 表示通过for循环的索引值,表示数列的第一个元素) * n 表示数列的最后一个值,通过运算 直接求出 * * 用上述符号替代原公式,得到如下公式 * (i + n)(n - i + 1) / 2 = a * * 拆分之后,就变成了一个二次函数 * 2 * a = n ^ 2 - n * i + n + n * i - i ^ 2 + i * 2 * a = n ^ 2 + n - i ^ 2 + i * 根据二次函数的求根公式求解 n 的值 (-b + sqrt(b ^ 2 -4ac)) / 2a 得出 n 的值 * n ^ 2 + n - i ^ 2 + i - 2 * a = 0 * b ^ 2 -4ac 的值如下 * 1 - 4 (i - 2 * a - i ^ 2); * * n 的两个解如下 * (-1 + Math.sqrt(1 - 4 (i - 2 * a - i * i))) / 2 * (-1 - Math.sqrt(1 - 4 (i - 2 * a - i * i))) / 2 * * 判断以下得到的 n 是否为一个整数(得到的结果为一个double类型) 为整数则说明从当前位置(i)出发 有连续的整数 和为 a * */ public static int get(int a) { // 记录返回结果 int res = 0; for (int i = 0; i < a; i++) { // b1 即为 ”n“ 对应的索引下标,只不过使用double表示 double b1 = (-1 + Math.sqrt(1 - 4 * (i - 2 * a - i * i))) / 2; // 因为这个解为负数,所以不考虑 //double b2 = (-1 - Math.sqrt(1 - 4 * (i - 2 * a - i * i))) / 2; System.out.println(b1); // 判断解是否为一个整数 if (b1 - (long) b1 == 0) { res++; } } return res; } }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int ans = getSum(n); System.out.println(ans); } /* i = 1时,n % 1 == 0,本身就是一个结果 i = 2时,因为是连续整数,所以有a + a + 1 = n => 如果(n - 1) % a == 0 那么就存在这个结果a */ public static int getSum(int n){ if(n == 0) return 1; int ans = 0,i = 1; while(n > 0){ if(n % i == 0){ //如果n能整除i,说明存在结果 ans ++; }i n -= i; //(这里就让n - i) i += 1; //(i递增) } return ans; } }
package com.question.bilibili; //给定一个正整数N,试求有多少组连续正整数满足所有数字之和为N? (1 <= N <= 10 ^ 9) import java.util.Scanner; public class Solution4 { /** * * @param num 正整数N * @return 多少组连续数 */ public static int findContinuousSequencesCount(int num){ if(num <= 1) return 1; //计数值 int count = 0; int low = 1; int high = 2; //low 表示左边界 //high 表示右边界 while(high > low){ //具体值 int sum = (low + high) * (high - low + 1) / 2; if(sum == num){ count++; //值偏大 low++; }else if(sum > num){ //调整左边界 让值变小 low++; } //调整右边界 让值变大 else high++; } //自己本身 return ++count; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int num = scanner.nextInt(); System.out.println(findContinuousSequencesCount(num)); scanner.close(); } }
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner s = new Scanner(System.in); int input = s.nextInt(); System.out.println(getNum(input)); } public static int getNum(int border){这题有问题,非要给个0,导致0+1+2+3+4+5=15,1+2+3+4+5=15,这就是两次了,导致结果出错。咳,我这个超时了int n=0;if(border==0){
n=1;
return n;
}
for(int i=1;i<=border;i++){ int count=0; for(int j=i;j<=border;j++){ count+=j; if(count == border){ n++; break; }else if(count>border){ break; } } } return n; } }
class Solution { public: /* 直接求算法复杂度有点大 转为为o(logn) 求因子 推导过程: (start + end)(end - start +1) = 2*N; 设 start + end = i; 上式变为:(start + end)(end - start) + (start + end) = 2*N => (end - start)*i +i = 2*N; 由上面2个式子可以求出 end=(2*N/i+i-1)/2,start=end-2*N/i+1. 代码按照上面的写行 */ int consecutiveNumbersSum(int N){ int res = 1;//1*本身算一个 //i 表示其中的一个因子 所以i开始从2取 for(int i=2;i<=sqrt(2*N);i++){ if(2*N % i == 0){//肯定能整除 int end = (2*N/i +i -1)/2; int start =end - 2*N/i +1; if((start + end)*(end - start+1) == N*2){ res++; } } } return res; } };
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { ll n; cin >> n; ll res = 0; if(n == 0) { cout<<1<<endl; return 0; } ll m = 2*sqrt(2*n); // k^2 + (2a-1)*k - 2*N = 0 //k为期间长度,a为起始,枚举k for(ll k = 1 ;k<m;k++) { if( (2*n - k*k + k)%(2*k) == 0 && (2*n - k*k + k)/(2*k) > 0) { //cout<<k<<" "<<(2*n - k*k + k)/(2*k)<<endl; res++; } } cout<<res<<endl; return 0; }
#include<bits/stdc++.h> using namespace std; int main(){ int num; while(cin>>num){ int tmp_num=1; int left=1,right=1; // 区间明确定义 int res=1; for(;left<=(num>>1) ;){ if(tmp_num==num){ res++; tmp_num-=left++; tmp_num+=++right; } else if(tmp_num<num){ tmp_num+=++right; } else{ tmp_num-=left++; } } cout<<res<<endl; } }使用双指针法。 O(N) 如果想更高效,可以考虑使用等差数列公式。