CF-div3-624-D. Three Integers

小结:剪枝优化,Ologn枚举

代码1 枚举1个倍数,贪心判C

nlogn
枚举A的值
枚举A的j倍->算B
计算C: C有两种方案以保证开销最小上限和下限(尽可能靠近"新B的倍数")

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

/*
nlogn
枚举A的值 
枚举A的j倍->算B
计算C: C有两种方案以保证开销最小上限和下限(尽可能靠近"新B的倍数") 
*/


int t;
int a,b,c; 
int main(){
	cin>>t;
	while(t--){
		cin>>a>>b>>c;
		int ansA = b,ansB = b,ansC = b;
		int ans = abs(b - a) + abs(c - b);
		for(int A=1;A<=20015;A++){ //枚举A的值 
			for(int j=1;j*A<=20015;j++){ //枚举A的j倍 
				int B = A*j;
				int C1 = c/B*B; //计算C   
				int C2 = (c/B+1)*B;
				if(abs(a-A) + abs(B-b) + abs(C1-c) <= ans){
					ansA = A,ansB = B,ansC = C1;
					ans = abs(a-A) + abs(B-b) + abs(C1-c);
				}
				if(abs(a-A) + abs(B-b) + abs(C2-c) <= ans){
					ansA = A,ansB = B,ansC = C2;
					ans = abs(a-A) + abs(B-b) + abs(C2-c);
				}
			}
		}
		cout<<ans<<endl;
		cout<<ansA<<" "<<ansB<<" "<<ansC<<endl;
	}
	return 0;
}

/*
8
1 2 3
123 321 456
5 10 15
15 18 21
100 100 101
1 22 29
3 19 38
6 30 46

*/

代码2 枚举2个倍数

#include <iostream>  
using namespace std;  
typedef long long ll;
int main(){
	int t;
	cin>>t;
	while(t--){
		int a,b,c;
		cin>>a>>b>>c;
		int ans = abs(a-b)+abs(c-b);
		int mydata = b,mydatb = b,mydatc = b;
		for(int A = 1;A<=20005;A++){ //枚举新的值A    O(nlogn) 
			for(int j = 1;A*j<=20005;j++){  //枚举A的倍数 B  
				for(int k = 1;A*j*k<=20005;k++){ //枚举B的 倍数C
					int t = abs(a-A)+abs(b-A*j)+abs(c-A*j*k);
					if(ans>t){
						ans = t;
						mydata = A;
						mydatb = A*j;
						mydatc = A*j*k;
					}
				}
				
			}
		}
		printf("%d
",ans);
		cout<<mydata<<" "<<mydatb<<" "<<mydatc<<endl;
	}
	return 0;
}

代码3 枚举2个倍数 + 剪枝优化

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const int N = 2e5 + 10;

// 枚举的时候剪枝  ++ 变成 +倍数 
 
int main(){
    int t, a, b, c;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d%d", &a, &b, &c);
        int ans = inf;
        int A, B, C;
        for(int i = 1; i <= 15000; ++i){
            for(int j = i; j <= 15000; j += i){ //剪枝 因为成倍数关系 +=i 越后面速度速度快 
                for(int k = j; k <= 15000; k += j) { //剪枝 因为成倍数关系 
                    int tmp = abs(a - i) + abs(b - j) + abs(c - k);
                    if(ans > tmp){
                        ans = tmp;
                        A = i;
                        B = j;
                        C = k;
                    }
                }
            }
        }
        cout<<ans<<'
';
        cout<<A<<' '<<B<<' '<<C<<'
';
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fisherss/p/12384487.html