一、刷题统计
题面:小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a 道题目,周六和周日每天做 b道题目。
请你帮小明计算,按照计划他将在第几天实现做题数大于等于 n
题?
对于 50%的评测用例,1≤a,b,n≤106,对于 100%的评测用例,1≤a,b,n≤1018。
总结:简单模拟,但是数据开的很大,第一次做的时候发现只能过部分数据。所以在省赛时需要计算 O(n) 来确保简单题目稳定拿分。
二、修剪灌木
简单模拟
三、x进制
题面:进制规定了数字在数位上逢几进一。X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某种 X进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则 X进制数 321转换为十进制数为 65。现在有两个 X进制表示的整数 A和 B,但是其具体每一数位的进制还不确定,只知道 A和 B是同一进制规则,且每一数位最高为 N进制,最低为二进制。请你算出 A−B 的结果最小可能是多少。请注意,你需要保证 A 和 B 在 X进制下都是合法的,即每一数位上的数字要小于其进制。
代码:
#include<iostream>
using namespace std;
const int N=1e5+10,MOD=1000000007;
typedef long long LL;
LL ans;
int rec[N];//记录最终的数位数位
LL mul[N];//记录每一位的权重
int n,ma,mb;//最大进制,a的数位,b的数位
int a[N],b[N];//a与b中存的数字
int main()
{
cin>>n>>ma;
for(int i=ma-1;i>=0;i--)
{
cin>>a[i];
//cout<<a[i];
}
cin>>mb;
for(int i=mb-1;i>=0;i--)
{
cin>>b[i];
//cout<<b[i];
}
rec[0]=max(max(a[0],b[0])+1,2);
/*每一位的权重至少比该位的数大一
,并且考虑到当前位可能是0-0的情况*/
mul[0]=rec[0];
ans=a[0]-b[0];
for(int i=1;i<ma;i++)
{
rec[i]=max(max(a[i],b[i])+1,2);
// cout<<i<<" "<<rec[i]<<endl;
mul[i]=(mul[i-1]*rec[i])%MOD;
ans=(ans+mul[i-1]*(a[i]-b[i]))%MOD;
//cout<<ans<<endl;
}
cout<<ans<<endl;
}
总结:
x进制题目较为难以理解的地方就是,321怎么变成65的
可以通过,(x进制)321=3*(102)+22+1=65(十进制)理解一下。
以3转换为10进制作为例子,3 * 8^2,因为其低数位并不是逢8进一,而是逢二进一再逢十进一,所以3转化为10进制是3102。
由于需要求得最小差值,当数字确定的情况下,让每个数位的进制都为最小即可。
困扰我的是,如何去进行取模从而使数字不溢出数据范围
如下面的类似阶乘式的计算取模是否与完全计算出来后再取模是一样的?
mul[i]=(mul[i-1]*rec[i])%MOD;
由取模的结合律
((a* b) % p * c)% p = (a * (b*c) % p) % p
可以得知都是一样的。
四、