Codeforces 1294(A,B,C,D)Round #615(Div.3)

题目链接:https://codeforces.com/contest/1294
A. Collecting Coins
题意:三姐妹分别有a,b,c个硬币,先让你把n个硬币分给三姐妹,使得她们的硬币数相同,如果能实现输出YES,否则输出NO。
思路:此题应注意是三姐妹接受硬币(可以为0),但是不能减少原有硬币数。
代码实现:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e5+5;
int main()
{
    int t; cin >> t;
    while(t -- ){
        int a, b, c, n;
        cin >> a >> b >> c >> n;
        if(a < b) {int t = a; a = b; b = t;}
        if(a < c) {int t = a; a = c; c = t;}
        if(b < c) {int t = b; b = c; c = t;}
        //先让a,b,c都变成max(a, b, c)
        int x = 2 * a - b - c;
        if(n >= x && (n - x) % 3 == 0)
            cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

B. Collecting Packages
题意:机器人要在坐标图上手机n个包裹,但是它只能向上移动(‘U’)和向右移动(‘R’)。换句话说,机器人可以一步移动从点(x,y)到点(x + 1,y)或点(x,y + 1)。机器人想以最少的步数手机完n个包裹,如果可行输出YES并输出字典序最小的路径,否则输出NO。
在这里插入图片描述
思路:显然我们可以定义结构体并进行排序(先满足横坐标升序,再满足纵坐标升序),然后就是遍历找到答案啦。
代码实现:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int INF=0x3f3f3f3f;
const int N = 1e5+5;

struct node{
  int x,y;
}s[N];

bool cmp(node a, node b)
{
    if(a.x < b. x) return 1;
    else if(a.x == b. x){
        if(a.y < b.y) return 1;
        else return 0;
    }
    else return 0;
}

int main()
{
    int t;
    cin >> t;
    while(t -- ){
        int n, vis = 0;
        string ans;
        cin >> n;
        for(int i = 1; i <= n; i ++ )
            cin >> s[i].x >> s[i].y;
        sort(s + 1, s + n + 1, cmp);
        
        for(int j = 1; j <= s[1].x - 0; j ++ )
            ans += 'R';
        for(int j = 1; j <= s[1].y - 0; j ++ )
            ans += 'U';
         
        for(int i = 2; i <= n; i ++ ){
            if(s[i].x == s[i-1].x){
                if(s[i].y > s[i - 1].y){
                    for(int j = 1; j <= s[i].y - s[i - 1].y; j ++ )
                        ans += 'U';
                }
                else{
                    cout << "NO" << endl;
                    vis = 1;
                    break;
                }
            }
            if(s[i].y == s[i - 1].y){
                if(s[i].x > s[i - 1].x){
                    for(int j = 1; j <= s[i].x - s[i - 1].x; j ++ )
                        ans +='R';
                }
                else{
                    cout << "NO" << endl;
                    vis = 1;
                    break;
                }
            }
            if(s[i].x > s[i - 1]. x){
                if(s[i].y > s[i - 1].y){
                     for(int j = 1; j <= s[i].x - s[i - 1].x; j ++ )
                        ans += 'R';
                     for(int j = 1; j <= s[i].y - s[i - 1].y; j ++ )
                        ans += 'U';
                }
                else if(s[i].y == s[i - 1].y) ;
                else{
                    cout << "NO" << endl;
                    vis = 1;
                    break;
                }
            }
        }
        if(!vis) cout << "YES" <<endl << ans << endl;
        ans.clear();
    }
    return 0;
}

C. Product of Three Numbers
题意:您会得到一个整数n。 找出三个不同的整数a,b,c使得2≤a,b,c和a⋅b⋅c= n输出YES和a b c,否则输出NO。
思路:其实相当于找到n的两个因子a和y,再找到y的两个因子b和c,使得a * b * c = n(且a,b,c互不相同);首先得判断n和y是否能得到两个不同得因子相乘等于自身,再进行处理(每次遍历到二次跟就好)。
代码实现:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e5+5;
int v[N];
ll cmp(ll x)
{
    ll y = sqrt(x);
    for(ll i = 2;i <= y;i++)
        if(x % i == 0 && !v[i])
            return i;
    return 0;
}
int main()
{
    int t; cin >> t;
    while(t--){
        memset(v,0,sizeof(v));
        ll a[5], n; cin >> n;
        if(!cmp(n)){
            cout << "NO" << endl;
            continue;
        }
        else{
            ll p = cmp(n);
            a[0] = p;
            v[p] = 1;
            n /= p;
        }
        if(!cmp(n)){
            cout << "NO" << endl;
            continue;
        }
        else{
            ll p = cmp(n);
            a[1] = p;
            v[p] = 1;
            n /= p;
            a[2] = n;
            sort(a,a+3);
            if(a[0] != a[1] && a[0] != a[2] && a[1] != a[2])
                cout << "YES" << endl << a[0] << " " << a[1] << " " << a[2] << endl;
            else cout << "NO" << endl;
        }
    }
}

D. MEX maximizing
题意:刚开始有一个空集合,会往里添加q次数,每次加一个值,而且你可以让这个数任意加减x若干次,每次添加后就查询当前最小的不属于这个集合的非负整数是什么。尽可能让这个最小的不属于这个数列的非负整数最大。
**思路:**由于每次添加的数t都可以加减任意次的x,故我们只需记录t%x,用num[i]表示i的个数,用res来查询是否可以满足要求,如果num[res%x]不为0,说明之前有一个没发挥作用的t可以用来顶替该位置上的res,说嘛现在的res就不是答案。
代码实现:

#include<bits/stdc++.h>
using namespace std;
const int N = 4e5 + 5;
int num[N];

int main()
{
    int q, x;
    cin >> q >> x;
    int res = 0;
    while (q -- ){
        int t;
        cin >> t;
        num[t % x] ++ ;
        
        while (num[res % x]){
            num[res % x] -- ;
            res ++ ;
        }
        cout << res << endl;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值