Atcoder ABC 161 B-D(B-注意向上取整, C-简单数学, D-队列,枚举)

B - Popular Vote

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题意:

有n个商品要你挑选出前m个最多票的,且要满足大于等于 tot/4*m(tot为总票数)。

思路1:

  1. 降序排序,之后看第m个是否满足题意。

思路2:

  1. 先求出总票数,之后算出条件 tot/4*m。
  2. 遍历一遍,看看是否有满足条件的存在,满足就cnt++;
  3. 最后看cnt>=m是否成立。

反思

虽然题目没明说,但其实是要向上取整

AC(思路2)

#include <iostream>
#include <vector>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
int main()
{
    int n, m,sum,x;
    vector<int>v;
    cin>>n>>m;
    sum=0;
    For(i,1,n)
    {
        cin>>x;
        sum+=x;
        v.push_back(x);
    }
    sum=(sum+m*4-1)/(m*4);//注意要向上取整!!!!!
    int cnt=0;
    int len=v.size();
    For(i,0,len-1)if(v[i]>=sum)cnt++;
    if(cnt>=m)cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
    return 0;
}

C - Replacing Integer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题意:

给你一个数,问你最终转换成多少次可以使n最小。

思路:

  1. 对于当n>=k时,肯定不是最小,所以要先缩小到小于k。
  2. 缩小即是n%k。这里设t=n%k。
  3. 对于缩小了的n,即t,继续缩小,n=|t-k|=k-t。
  4. 可是再缩小呢 n=k-(k-t)=t,即变回t了。
  5. 这里想起数电的, t 和 k-t 以模数 k 互补。
  6. 所以ans=min(t,k-t)。

反思

写这题时,其实可以拿草稿纸出来推一下,

AC(官方)

#include <iostream>
#include <cmath>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
typedef long long ll;
const ll INF =0x3f3f3f3f3f3f3f3f;
int main()
{
    ll n, k,ans;
    cin>>n>>k;
    n=n%k;
    ll temp=abs(n-k);
    ans=min(temp,n);
    cout<<ans<<endl;
    return 0;
}

AC(博主contest时的)

#include <iostream>
#include <cmath>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
typedef long long ll;
const ll INF =0x3f3f3f3f3f3f3f3f;
int main()
{
    ll n, k,ans;
    cin>>n>>k;
    ans=n;
    if(n>k)
    {
        n=n%k;
        ans=min(ans,n);//想清楚,这里余数
    }
    //走到这里肯定n比k小,所以再判定一下
    ll temp=abs(n-k);
    ans=min(temp,ans);
    cout<<ans<<endl;
    return 0;
}

D - Lunlun Number

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题意:

数字要满足每一位上的数和相邻的数差距最多是1。

思路&&反思

  1. 起初我无从下手。
  2. 后面看了题解,其实可以用队列去维护。
  3. 先把1-10入队,之后第k次出队就是答案了
    在这里插入图片描述

哎哎哎,对于这道题完美的符合了先进先出的原则。
1->10/11/12
其中10->100/101.
当十位都出队 保证 考虑完了10位,紧接着就是最小的百位。

AC(官方)

#include <iostream>
#include <cmath>
#include <queue>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
typedef unsigned long long ull;
queue<ull>q;
int main()
{
    int k;
    For(i,1,9)q.push(i);
    cin>>k;
    ull temp,pre;
    For(i,1,k)
    {
        pre=q.front();q.pop();
        if(pre%10)//最后一位是10
        {
            temp=pre*10+(pre%10)-1;
            q.push(temp);
        }
        temp=pre*10+pre%10;
        q.push(temp);cnt++;
        if(pre%10!=9)//最后一位是9,就没有进位的可能了
        {
            temp=pre*10+pre%10+1;
            q.push(temp);
        }
    }
    cout<<pre<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章