#poj:Fair Distribution

poj:Fair Distribution

#题目描述
在这里插入图片描述

#大概意思要你找到一个最短的方式来使得n * k = m 成立 n只能减小 m只能增加 k为任意一整数
#n减少的数加上m增加的数的和最小
#看着好像只能暴力的算 但是定睛一看 范围 1e8 直接暴力能想到会超时 自己写也是各种优化都来试试撞运气还是卡时间 还要优化算法

#知识点
分块 (我是没看出来-别的大佬说的(⊙ˍ⊙))

#代码

#include<bits/stdc++.h>
using namespace std;
#define maxn 1e9
int n,m;

int main()
{
    int t;
    cin >> t;
    for(int i=1; i<=t; i++)
    {
        cin >> n >> m;
        if(m % n == 0)
        {
            cout << 0 <<endl;
            continue;
        }
        if(m < n)
        {
            cout <<n - m <<endl;
            continue;
        }
        else//问题是咋这样想啊  一般都都只会想到下面的i是x   这个将temp也用上了  能用temp 就用temp 否则就用i
        {
            int ans = maxn;
            for(int i=1; i<=n&&i*i <= m; i++) ///!!! i*i 关键  这个限制条件效果很好
            {
                int temp = (m+i-1)/i;///向上取整  temp  和 i 都有可能是x   x * k = m
                if(n >= temp)//temp 是x
                {
                    int cnt = (m + temp - 1)/temp;//cnt 是 k 向上取整过的  所以*x后 会大于m
                    ans = min(ans, min(n-i,n-temp+cnt*temp - m));//min 中 n-i为整除的情况 后一种就是正常情况
                }
                else // i 是x  temp 太大了 不能为n  x应该小于n
                {
                    ans = min(ans,n-i+i*temp-m);//!!! 这个temp是向上取整过的  否则要 n-i + m - m%i
                }
            }
            cout << ans <<endl;
        }
    }
    return 0;
}

#总结
学习了大佬的算法 一眼看过去看不懂 蒟蒻(汗 ~ : P)自己分析了好久才弄的 但是还是不知道为什么要这样弄 先学会了再说吧 不会就自己带个数据跑一遍就又会了一点点 (⊙.⊙) 就嗯推 没那个悟性

POJ2499—二叉树问题 时间限制:1000ms,空间限制:65536K。 问题描述:二叉树是计算机科学中常见的数据结构。在本问题中,我们将看到一棵非 常大的二叉树,其中结点包含一对整数,树的构造如下: (1)根包含整数对(1,1)。 (2)如果一个结点包含(a,b),则其左孩子结点包含(a+b,b),右孩子结点包含 (a,a+b)。 该问题是给定上述二叉树的某个结点的内容(a,b),假设你沿着最短的路径从树根 行走到给定结点,你能否知道需要经过左孩子的个数(走左路步数)和右孩子的个数(走 右路步数)。 输入格式:第一行包含场景个数。每个场景由一行构成,包含两个整数 i 和 j(1≤i,j ≤2×10^9)的结点(i,j),你可以假设这是上述二叉树中的有效结点。 输出格式:每个场景的输出都以"Scenario #i:"的行开头,其中 i 是从 1 开始的场景编号。 然后输出包含两个数字 l 和 r 的单行(用空格分隔),其中 l 和 r 分别表示从树根遍历到输入的结点需要经过左、右孩子的个数,在每个场景后输出一个空行。 输入样例: 3 42 1 3 4 17 73 输出样例: Scenario #1: 41 0 Scenario #2: 2 1 Scenario #3: 4 6 要求:解题代码要包含丰富的注释并提供详细的算法设计思路,思路分为输入、处理和输出三个部分。用Java语言解题。允许一次输入多个测试用例,并一次性输出多个输入对应的所有结果。
最新发布
11-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值