萌新噩梦———三元组

有这么一道题,在学习基础算法的初期,这一道题曾让多少萌新对于它是无从下手,只能靠循环遍历蹭时间来获取那微弱的一点点分。

问题描述

给定一个整数和N,K。三元组数(a,b,c)满足三元关系:a+b,a+c,b+c都是k的倍数。注意a,b,c的顺序不能改变,但是它们数值可以相同。请找出a,b,c均不大于N的三元组个数。

输入格式

输入两个整数N,K,中间用空格隔开。

N K

输出格式

输出三元组个数。

样例输入     3 2                                          样例输出     9
样例输入     5 3                                          样例输出     1
样例输入     31415 9265                            样例输出     27
样例输入     35897 932                              样例输出     114191

样例一说明:

(1,1,1),(1,1,3),(1,3,1),(1,3,3),(2,2,2),(3,1,1),(3,1,3),(3,3,1),(3,3,3)满足条件。

做法

这一道题不能用循环来找a,b,c。

思路:

找k的倍数一共有两种情况。

1 两个数都为k的倍数,那两数之和肯定为k的倍数。

2 两个数都不为k的倍数,但相加为k的倍数。

定义两个变量a,b。

其中一个用于储存在n范围内k的倍数的个数

那么在第一种情况下,就一共有a*(a-1)*(a-2)种。

注意:这里还有一种特殊情况其中两数相同而剩下一数不同,且都为k的倍数

又有(a-1)*a+a 种情况。

第二个变量用来判断第二种情况,即两数除与k的余数都为k/2,那么尽管两个数都不为k的倍数,但相加为k的倍数。但在这种情况下,k必须为2的倍数才有可能。

这时有b*(b-1)*(b-2)+(b-1)*b+b 种情况。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a,b; 
int N=1000001;
ll n,k,ans;
int main(){
    cin>>n>>k;
    a=n/k;
    b=n/k+(n%k>=k/2);
    ans=(ll)a*(a-1)*(a-2)+3ll*(a-1)*a+a;
    if(k%2==0) 
	ans+=(ll)b*(b-1)*(b-2)+3ll*(b-1)*b+b;
    cout<<ans;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值