题解:P14166 [Algo Beat Contest 002.5 A] 题目分配 (divide)
容易发现,在
接下来,我们处理最大差。
我们让前
其中,前
最后,我们处理最小值。
我们先让
特别注意,需要开
unsigned long long
注释版完整代码:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
ll sum1(ll n){
return n*(n+1)/2;
}
/*
n 个人最少完成题数为 sum1(n),如果 m 小于 sum1(n),则输出 -1
*/
bool v(ll n,ll m){
return m<sum1(n);
}
/*
max:让 n - 1 个人分配的 1 , 2 , …, n-1 题,剩下的全给第 n 个人
*/
ll mx(ll n, ll m){
ll s=sum1(n-1);
ll x=m-s;//第n个人分配的题数
return x-1;
}
/*
min:在基础分配 1 , 2 , …, n 的前提下,将剩余题数平均分配
*/
ll mn(ll n, ll m){
ll s=sum1(n);//分配题数
ll d=m-s;//剩余题数
ll k=d/n;//每人平均可额外分配的题数
ll r=d%n;//分配后剩余的题数
ll mi=1+k;//基础最小值(1) + 平均额外分配数k
ll ma=n+k+(r>0?1:0);//基础最大值(n) + 平均额外分配数k (如果有剩余题数则+1)
return ma-mi;
}
int main(){
int T;
cin>>T;
while(T--){
ll n,m;
cin>>n>>m;
if(v(n,m)){
puts("-1 -1");
continue;
}
cout<<mx(n,m)<<" "<<mn(n,m)<<"\n";
}
return 0;
}
无注释代码:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
ll sum1(ll n){return n*(n+1)/2;}
bool v(ll n,ll m){return m<sum1(n);}
ll mx(ll n, ll m){ll s=sum1(n-1),x=m-s;return x-1;}
ll mn(ll n, ll m){ll s=sum1(n),d=m-s,k=d/n,r=d%n,mi=1+k,ma=n+k+(r>0?1:0);return ma-mi;}
ll n,m,_;
int main(){
cin>>_;
while(_--){
cin>>n>>m;
if(v(n,m)){cout<<"-1 -1\n";continue;}
cout<<mx(n,m)<<" "<<mn(n,m)<<"\n";
}
return 0;
}