BestCoder Round #60 HDOJ5504 5505 5506题解

题目链接:点击打开链接


A: 读入数据的时候先把非0的乘到一起, 然后对n分类讨论, n为1直接输出a[0], 0的个数为n输出0. 而后对ans分类讨论, 大于0直接输出, 

小于0的时候, 若0的个数为n - 1输出0, 其他情况则找到绝对值最小的负数除掉就为答案.

AC代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 100;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int main(int argc, char const *argv[])
{
    int t, n;
    scanf("%d", &t);
    while(t--) {
        ll ans = 1, num = 0, a[MAXN];
        bool flag = false;
        scanf("%d", &n);
        for(int i = 0; i < n; ++i) {
            scanf("%lld", &a[i]);
            if(a[i]) ans *= a[i];
            else num++;
        }
        if(n == 1) {
            printf("%lld\n", a[0]);
            continue;
        }
        if(num == n) {
            printf("0\n");
            continue;
        }
        if(ans > 0) printf("%lld\n", ans);
        else if(n - num == 1) printf("0\n");
        else  {
            ll m = -INF;
            for(int i = 0; i < n; ++i)
                if(a[i] < 0 && a[i] > m) m = a[i];
            printf("%lld\n", ans / m);
        }
    }
    return 0;
}


B: m无法整除n则ans为-1. 其他情况则首先m自除n, 而后m不为1时, 每次求出m n的gcd, m自除gcd, n乘gcd, gcd为1时ans也为-1.

AC代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
typedef unsigned long long ull;
ull n, m;
ull gcd(ull x, ull y)
{
    return y == 0 ? x : gcd(y, x % y);
}
int main(int argc, char const *argv[])
{
    int t;
    scanf("%d", &t);
    while(t--) {
        scanf("%lld%lld", &n, &m);
        if(m % n != 0) {
            printf("-1\n");
            continue;
        }
        ull ans = 0, x;
        m /= n;
        while(m != 1) {
            x = gcd(m, n);
            n *= x;
            m /= x;
            ans++;
            if(x == 1) break;
        }
        if(m != 1) printf("-1\n");
        else printf("%lld\n", ans);
    }
    return 0;
}


C: 首先要转化, 给你n组数, 每次可以指定一个数, 包含这个数的那一组可以被删掉, 问你l次操作能不能使所有集合都被删掉. 注意到题目

中数据的范围, 直接暴力. 最后通过判断vis数组是否全为true即可.

AC代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "vector"
using namespace std;
const int MAXN = 305;
vector<int> v[MAXN];
int n, l;
bool vis[MAXN];
int main(int argc, char const *argv[])
{
    int t;
    scanf("%d", &t);
    while(t--) {
        memset(vis, false, sizeof(vis));
        for(int i = 0; i < MAXN; ++i)
            v[i].clear();
        scanf("%d%d", &n, &l);
        for(int i = 1; i <= n; ++i) {
            int a;
            scanf("%d", &a);
            for(int j = 0; j < a; ++j) {
                int x;
                scanf("%d", &x);
                v[x].push_back(i);
            }
        }
        for(int i = 0; i < l; ++i) {
            int m = -1, val = -1;
            for(int j = 0; j < MAXN; ++j) {
                int x = 0;
                for(int k = 0; k < v[j].size(); ++k)
                    if(!vis[v[j][k]]) x++;
                if(x > m) {
                    m = x;
                    val = j;
                }
            }
            if(val >= 0)
                for(int j = 0; j < v[val].size(); ++j)
                    vis[v[val][j]] = true;
        }
        bool flag = false;
        for(int i = 1; i <= n; ++i)
            if(!vis[i]) {
                flag = true;
                break;
            }
        if(flag) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值