CF774G Perfectionist Arkadiy

思維和構造題

題目給定 h,w 和 a,需要我們找出最小的x,其中h,w,a都是整數。

對於row和col 的a 都是比x 小一個的,我們嘗試自己加一個a,讓題目變的簡單一點。

我們把橫軸上 a 的數量設為 n, 豎軸上的a的數量設為m。

那麼新的 h w 和 a x 的關係式就變為,

(a + x)(n + 1) = h + a

(a + x)(m + 1) = w + a

h 和 a 是整數 所以h + a 是整數,並且a + x 是h + a 和 w + a 的公因數,姑且把a + x 記為k

則有

k | h + a,\;k|w+a

k_{max} = gcd(h + a, w + a)

\\k_{max}=a+x\\k_{max}-a =x

x不可能是負數,所以k 至少要大於a。

那麼我們思考如何讓 x 最小?

那就是讓 k 儘量接近 a。

k_{min}=\frac{k_{max}}{p}

\frac{k_{max}}{p}\geq a-------(1)

那p要取什麼值才能,讓上面的式子最小呢?

\frac{k_{max}}{a}\geq p

顯然讓 p = k/a 的下去整是最優選擇,rounding down k/a 不然無論怎麼算都會算到k min 等於a。

ans = \frac{k_{max}}{[\frac{k_{max}}{a}]}

代碼

gcd 模板

int gcd(int a, int b){
    if(b == 0)return a;
    gcd(b, a % b);
}

題目需要一點特判,就是a比h或w大就要返回-1,如果a比gcd要大也是不成立的,所以返回-1,因為在(1)我們知道x是要比a大的。

ans : 

#include<iostream>
using namespace std;
int a, h, w;
double ans = 0;
int gcd(int a, int b){
    if(b == 0)return a;
    return gcd(b, a % b);
}
int main(){
    cin >> a >> h >> w;
    int g = gcd(h + a, w + a);
    if(g < a || a > h || a > w){
        cout << -1;
    }else{
        ans = (double)g/(g/a) - a;
        printf("%.6f",ans);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值