E
题意:
问 x y z 的空间。问体积为k 的立体(长宽高随意)最多有几种摆法。
因为x y z 的范围小 只有2000.所以我们可以枚举长 和宽 ,高通过体积计算。
确定好长宽高之后,摆法就是 (x-长+1)(y-宽+1)(z-高+1)
相乘。(其实就是 在长的方向上 选出一定连续长度的 的不同取法,在宽的方向,在高的方向。三个相乘)
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
int ans=0;
int x,y,z,k;
cin>>x>>y>>z>>k;
if (x*y*z<k){
cout<<0<<"\n";
return ;
}
for (int i=1;i<=x;i++)
{
for (int j=1;j<=y;j++)
{
这里注意,int 和 double
double m=(double)k/(double)(i*j);
if (m!=(int)m||m>z)continue;
ans=max((double)ans,(x-i+1)*(y-j+1)*(z-m+1));
}
}
cout<<ans<<"\n";
}
signed main()
{
std::cin.tie(nullptr)->sync_with_stdio(false);
int t;cin>>t;
while(t--)
{
solve();
}
return 0;
}
F
题意:
敌人有 h 的血量,你有n种攻击。每种 攻击有 伤害 和cd 时间。
一开始,所有攻击都不处在cd时间内,问击杀boss的最少的回合数。
显然的这题是二分。具有单调性。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
int h,n;cin>>h>>n;
vector<int>a(n);
vector<int>c(n);
for (int i=0;i<n;i++)
cin>>a[i];
for (int i=0;i<n;i++)
cin>>c[i];
int l=1,r=1e11;
while(l<=r)
{
int mid=l+r>>1;
int sum=0;
for (int i=0;i<n;i++)
{
sum+=(mid+c[i]-1)/c[i]*a[i];
这里如果不berak,会爆long long ,这里有break 就会将sum控制在 h 的范围内,也就是 2e5
if (sum>=h) break;
}
if (sum>=h)
{
r=mid-1;
}
else l=mid+1;
}
cout<<r+1<<"\n";
}
signed main()
{
std::cin.tie(nullptr)->sync_with_stdio(false);
int t;cin>>t;
while(t--)
{
solve();
}
return 0;
}
G
题意:
显然的,要满足这个等式,那么n的每一位上的数 和k相乘都不能进位。也就是<=9
我们可以通过 9/k +1来计算,出来 0-9 中有 多少个数 满足。(这些数 才可以放到n 的数位上)。
例如 9/4=2,也就是 0 1 2,这三个数去构成n。个数记为cnt
现在就变成了一个 排列组和的问题了。
注意n 是左闭右开的。
n最多是r位,先不考虑左边界的问题。每一位上可以放cnt种数字。
那么一共有 cnt^r 。
现在来考虑左边界的问题。n 至少是l+1位,那么l位以及 以下的数字是不符合的。
所以上面的结果减去 cnt^l (这样计算包含了l位 和l位以下的,把0放前面就可以)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1e9+7;
int power(int a,int b)
{
int ans=1;
a%=mod;
while(b)
{
if (b&1){
ans=(ans*a)%mod;
}
a=(a*a)%mod;
b>>=1;
}
return ans;
}
void solve()
{
int l,r,k;cin>>l>>r>>k;
int cnt=9/k;
cnt++;
cout<<(power(cnt,r)-power(cnt,l)+mod)%mod<<"\n";
}
signed main()
{
std::cin.tie(nullptr)->sync_with_stdio(false);
int t;cin>>t;
while(t--)
solve();
return 0;
}