Codeforces Round #701 (Div. 2)

A

Add and Divide

题意:给你两个正整数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

Replace and Keep Sorted

题意:给你正整数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

Floor and Mod

题意:若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∈(k^{2}+k,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^{4} (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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值