A
题意:给你两个正整数a和b,每次操作可以将a改为a/b向下取整,或让b=b+1,求让a=0时的最小操作数。
思路:显然b=1时,必须先进行b=b+1。先求一直进行a=a/b的操作数记为ans,然后遍历b~b+ans,计算操作数,不断取最小。
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
ll a,b;
void solve()
{
cin>>a>>b;
int cnt=0;
int ans=0;
if(a==b) cout<<2<<'\n';
else if(a<b) cout<<1<<'\n';
else
{
ll aa=a,bb=b;
if(b==1) bb++,ans++;
while(aa!=0)
{
aa/=bb;
ans++;
}
for(int i=max(b,(ll)2);i<=b+ans;i++)
{
cnt=i-b;
aa=a;
while(aa!=0)
{
aa/=i;
cnt++;
}
ans=min(ans,cnt);
}
cout<<ans<<'\n';
}
}
int main()
{
//ios;
int _t=1;
cin>>_t;
while(_t--)
{
solve();
}
system("pause");
return 0;
}
B
题意:给你正整数k,若两个数组满足以下条件,则称两数组为k相似。
(1)它们是严格递增的
(2)它们具有相同的长度
(3)它们的元素在1~k的范围内
(4)它们只有一位不同
给你数组a[n],求在区间a[l]~a[r]的k相似数组的数量
思路:因为只有一位不同,可以在[l,r]枚举不同的位i,第一位不同时,第一位可以改为[1,a[l])(a[l],a[l+1]),共a[l+1]-2种选择,对于最后一位不同,可以改为(a[r-1],a[r])(a[r],k],共a[r]-2种选择.对于中间的位,可以改为(a[i-1],a[i])(a[i],a[i+1]),共a[i+1]-a[i-1]-2种选择。将l~r每位上的选择累加即为答案,得k+a[r]-a[l]-2*(r-l)-1
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
ll a[N];
ll n,q,k;
void solve()
{
cin>>n>>q>>k;
for(int i=1;i<=n;i++) cin>>a[i];
while(q--)
{
ll l,r;
cin>>l>>r;
ll ans=0;
cout<<(ll)(k+a[r]-a[l]-2*(r-l)-1)<<'\n';
}
}
int main()
{
ios;
int _t=1;
//cin>>_t;
while(_t--)
{
solve();
}
system("pause");
return 0;
}
C
题意:若a/b向下取整=a%b,则称(a,b)对儿是特殊的。给你两个正整数x和y,求1<=a<=x,1<=b<=y的(a,b)对儿的数量。
思路:首先⌊a / b⌋ == a % b 可以转化为,(设余数为k) a=kb+k (b > k)
由于b>k,所以a∈(,x],然后,将b看作自变量,a为因变量,所以当余数k确定后, a与b是唯一对应的.令a=x,b=x/k-1;所以b∈(k,x/k-1]
最终确定b的范围为b ∈ [1, y] ∩ (k, x / k - 1] = (k, min(y, x / k - 1)].
因为a与b是唯一对应的,所以对于每一个k, 就有 min(y, x / k - 1) - k 个 (a, b).
注意当从小到大枚举k时,b的范围是不断缩小的,注意判断无解的情况
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int t; cin >> t;
while (t--)
{
int x, y; scanf("%d %d", &x, &y);
ll res = 0;
for(int i=1;i<=x/i;i++)
{
res += max(min(y, x / i - 1) - i, 0); //与0取max, 是过滤无解的情况.
}
printf("%lld\n", res);
}
return 0;
}
D
Multiples and Power Differences
题意:给你一个n行m列的矩阵,让你构造出满足以下条件的矩阵b
(1)bij∈[1,1e6]
(2)bij是aij的倍数
(3)bij与相邻元素之差为 (k>=1)
思路:首先注意到输入的aij<=16,因此可以构造出一个数是所有aij的倍数(lcm)
用lcm处理1~16得这个数是720720,满足条件1.2,先用lcm填满矩阵b
考虑如何满足第三个条件,既要满足倍数关系,又要与相邻元素构造出差值,只能让lcm加上aij的四次方。注意相邻元素不能相等,要把这些值隔开,因此使用行列的奇偶性来判断
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define endl '\n'
#define sf(x) scanf("%d",&x)
#define rep(i,x) for(i=0;i<(x);i++)
#define gen(x) x##_
#define ios std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define PII pair<int,int>
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
using namespace std;
int n,m;
int a[510][510];
void solve()
{
int ans=1;
for(int i=1;i<=16;i++)
{
ans=ans*i/__gcd(i,ans);
}
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if((i+j)&1) cout<<ans<<' ';
else cout<<ans+a[i][j]*a[i][j]*a[i][j]*a[i][j]<<' ';
}
cout<<'\n';
}
}
int main()
{
ios;
int _t=1;
//cin>>_t;
while(_t--)
{
solve();
}
system("pause");
return 0;
}