C++ 求两对数的乘积绝对差最小
问题: 给定一个整数num,找出绝对差中最接近的两个整数,其乘积等于num+1或num+2 按任意顺序返回两个整数 我试过这个:C++ 求两对数的乘积绝对差最小,c++,algorithm,C++,Algorithm,问题: 给定一个整数num,找出绝对差中最接近的两个整数,其乘积等于num+1或num+2 按任意顺序返回两个整数 我试过这个: vector<int> closestDivisors(int num) { if(num == 1) return {1,2}; int first = num + 1, second = num + 2; std::vector<int> result(2); aut
vector<int> closestDivisors(int num) {
if(num == 1)
return {1,2};
int first = num + 1, second = num + 2;
std::vector<int> result(2);
auto vec1 = properDivisors(first);
auto vec2 = properDivisors(second);
std::map<int, std::pair<int,int>> m;
int min_k1 = INT_MAX;
for(auto it1 : vec1)
{
for(auto it2 : vec1)
{
if (it1 * it2 == first)
{
min_k1 = abs(it1-it2);
m[min_k1] = {it1, it2};
}
}
}
int min_k2 = INT_MAX;
for(auto it1 : vec2)
{
for(auto it2 : vec2)
{
if (it1 * it2 == second)
{
min_k2 = abs(it1-it2);
m[min_k2] = {it1, it2};
}
}
}
for(auto it : m)
{
result[0] = it.second.first;
result[1] = it.second.second;
if(result.size() == 2)
break;
}
return result;
}
std::vector<long long> properDivisors(int number) {
std::vector<long long> divisors ;
for ( int i = 1 ; i < number / 2 + 1 ; i++ )
if ( number % i == 0 )
divisors.push_back( i ) ;
return divisors ;
}
向量闭因子(int num){
如果(num==1)
返回{1,2};
int first=num+1,second=num+2;
std::向量结果(2);
auto vec1=属性指示器(第一);
auto vec2=属性指示器(秒);
std::map m;
int min_k1=int MAX;
用于(自动it1:vec1)
{
用于(自动it2:vec1)
{
如果(it1*it2==第一个)
{
min_k1=abs(it1-it2);
m[min_k1]={it1,it2};
}
}
}
int min_k2=int MAX;
用于(自动it1:vec2)
{
用于(自动it2:vec2)
{
如果(it1*it2==秒)
{
min_k2=abs(it1-it2);
m[min_k2]={it1,it2};
}
}
}
用于(自动it:m)
{
结果[0]=it.second.first;
结果[1]=it.second.second;
if(result.size()==2)
打破
}
返回结果;
}
标准::向量属性指示器(整数){
向量除数;
对于(int i=1;i
但我总是超过时间限制。有没有更有效的方法来实现这一点?向量的使用可能会使它比需要的慢得多。我将按以下方式处理 将
lo
设置为1
并将hi
设置为num+1
。这是获取两个整数的起点,两个整数相乘为所需值之一(相距较近的是1
和num+2
,因此可以忽略这种可能性)
然后,只需将lo
和hi
向对方移动(直到它们交叉),检查产品是否等于所需值。事实上,这两个数字正在接近,这意味着任何以后的成功都将使它们比以前的更接近
唯一棘手的一点是数字如何相互接近,但这比你想象的要简单。如果乘积小于num+1
,则减小hi
将意味着它离所需值更远,因此在这种情况下,您需要增加lo
另一方面,大于num+2
的乘积意味着您应该减少hi
(增加lo
将使乘积更高,从而远离期望值)
如果它等于num+1
或num+2
,则可以选择其中一个选项。这不重要的原因是因为lo+1
和hi
之间的绝对差异与lo
和hi-1
之间的绝对差异相同(a)
例如,下面是一个Python程序,它显示了它的实际功能:
num = int(input("Number: "))
lo = 1
hi = num + 1
found = None
while lo <= hi: # Make this '<' if numbers must be different.
prod = lo * hi
if prod == num + 1 or prod == num + 2:
found = (lo, hi)
mark = ' *'
else:
mark = ""
print(f"Low = {lo}, high = {hi}, product = {prod}{mark}")
if prod < num + 1:
lo += 1
else:
hi -= 1
print(found)
正如在评论中指出的,这只处理积极的输入。您也可以通过更改以下内容来满足负输入:
lo = 1
hi = num + 1
致:
这包含了解决方案的积极和消极领域,增加了一点额外的时间,但仍然非常快
(a) 我只对我的数学有99.99%的把握,因此,如果有人能提供一个反例,我很乐意编辑答案(或者甚至删除它,如果我不能解决它,尽管可能会在边缘案例中发现任何存在的问题,因此可能可以通过一些简单的预检查来解决)。让我知道。 这是C++中的代码。< /P>
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
if(v.size() - i == 1) {
cout << v[i];
} else {
cout << v[i] << ", ";
}
}
cout << "]"<<endl;
}
class Solution {
public:
vector <int> getDiv(int x){
int diff = INT_MAX;
vector <int> ret(2);
for(int i = 1; i * i <= x; i++){
if(x % i == 0){
int a = i;
int b = x / i;
int newDiff = abs(a - b);
if(newDiff < diff){
diff = newDiff;
ret[0] = a;
ret[1] = b;
}
}
}
return ret;
}
vector<int> closestDivisors(int num) {
vector <int> op1 = getDiv(num + 1);
vector <int> op2 = getDiv(num + 2);
return abs(op1[0] - op1[1]) <= abs(op2[0] - op2[1]) ? op1 : op2;
}
};
main(){
Solution ob;
print_vector(ob.closestDivisors(8));
}
// Output [3,3]
#包括
使用名称空间std;
无效打印向量(向量
Javascript代码
let num = 8; //Input
function getFactors(num) {
let factors = [1];
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) {
factors.push(i);
factors.push(num / i);
}
}
factors.push(num);
return factors;
}
(function getSmallAbsDiff() {
const factorsNplusOne = getFactors(num + 1).sort((a, b) => a - b);
const factorsNplusTwo = getFactors(num + 2).sort((a, b) => a - b);
const minOne = factorsNplusOne[factorsNplusOne.length / 2 - 1];
const maxOne = factorsNplusOne[factorsNplusOne.length / 2];
const minTwo = factorsNplusTwo[factorsNplusTwo.length / 2 - 1];
const maxTwo = factorsNplusTwo[factorsNplusTwo.length / 2];
maxOne - minOne < maxTwo - minTwo ? console.log(`[${maxOne}, ${minOne}]`) : console.log(`[${maxTwo}, ${minTwo}]`); // Output
})();
let num=8;//输入
函数getFactors(num){
设因子=[1];
for(设i=2;i a-b);
constfactorsnplustwo=getFactors(num+2).sort((a,b)=>a-b);
const minOne=factorsNplusOne[factorsNplusOne.length/2-1];
const maxOne=factorsNplusOne[factorsNplusOne.length/2];
const minTwo=factorsNplusTwo[factorsNplusTwo.length/2-1];
const maxTwo=factorsNplusTwo[factorsNplusTwo.length/2];
maxOne-minOne
您有没有可能用自己选择的语言纠正这种逻辑?它适用于负数?(我没有检查,但这是明显的未检查边缘情况)我怀疑从sqrt(num)
开始工作可以更有效地完成这项工作outwards@Donnie:说得好。您可以通过初始化来处理负数lo=-num-1
,hi=num+1
,如果lo>hi:(lo,hi)=(hi,lo)
。我将把它添加到答案中,而不是从lo=1和hi=num+1开始,并将lo和hi相互移动,从lo开始,您将获得更好的性能≈ 你好≈ √num和移动lo和hi使其彼此远离。这样,你一找到解决方案就可以退出。我发现问题陈述非常模糊,绝对值最接近的两个数字是什么意思?那句话可以用多种方式解释。。。
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
if(v.size() - i == 1) {
cout << v[i];
} else {
cout << v[i] << ", ";
}
}
cout << "]"<<endl;
}
class Solution {
public:
vector <int> getDiv(int x){
int diff = INT_MAX;
vector <int> ret(2);
for(int i = 1; i * i <= x; i++){
if(x % i == 0){
int a = i;
int b = x / i;
int newDiff = abs(a - b);
if(newDiff < diff){
diff = newDiff;
ret[0] = a;
ret[1] = b;
}
}
}
return ret;
}
vector<int> closestDivisors(int num) {
vector <int> op1 = getDiv(num + 1);
vector <int> op2 = getDiv(num + 2);
return abs(op1[0] - op1[1]) <= abs(op2[0] - op2[1]) ? op1 : op2;
}
};
main(){
Solution ob;
print_vector(ob.closestDivisors(8));
}
// Output [3,3]
let num = 8; //Input
function getFactors(num) {
let factors = [1];
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) {
factors.push(i);
factors.push(num / i);
}
}
factors.push(num);
return factors;
}
(function getSmallAbsDiff() {
const factorsNplusOne = getFactors(num + 1).sort((a, b) => a - b);
const factorsNplusTwo = getFactors(num + 2).sort((a, b) => a - b);
const minOne = factorsNplusOne[factorsNplusOne.length / 2 - 1];
const maxOne = factorsNplusOne[factorsNplusOne.length / 2];
const minTwo = factorsNplusTwo[factorsNplusTwo.length / 2 - 1];
const maxTwo = factorsNplusTwo[factorsNplusTwo.length / 2];
maxOne - minOne < maxTwo - minTwo ? console.log(`[${maxOne}, ${minOne}]`) : console.log(`[${maxTwo}, ${minTwo}]`); // Output
})();