zoukankan      html  css  js  c++  java
  • Codeforces Round #641 (Div. 2)

    A

    每次加一个最小因子(大于1), 但是由于k>1,

    1当f(n) = n (n为质数), --k, n += f(n), 使得f(n') = 2

    2 f(n) = a, n = a * c (a <= c) a为偶数2

    3 f(n) = a, n = a * c (a <= c) a为任意奇数(c也为任意奇数, 否则c可以拆为 2 * c', 则f(n) = a = 2), 则 --k, n' = a * (c + 1), c变偶数了, 则f(n') = a' = 2

    所以无论如何可以消耗一次k,使得f(n) = 2, 那剩下的无非就是 2 * (n / 2 + k)

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
     
    const int maxn = 1e5;
     
    int n, m, _;
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            ll n, k, a = 2, c; cin >> n >> k;
            while (n % a) ++a; c = n / a;
            if (c == 1) --k, c = a, a = 2;
            if (a != 2) --k, c = a * (c + 1) / 2, a = 2;
            cout << (c + k) * a << '
    ';
        }
        return 0;
    }
    

    B

    dp(不太好想), 好想的话, 还是写记忆化搜索

    直接看代码吧, 就是普通记忆化搜索

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
     
    const int maxn = 1e5 + 5;
     
    int n, m, _;
    int f[maxn], a[maxn];
     
    int dp(int u)
    {
        if (f[u]) return f[u];
     
        for (int i = 2; i * u <= n; ++i)
            if (a[i * u] > a[u])
                f[u] = max(f[u], dp(i * u));
        return ++f[u];
    }
     
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            cin >> n; int ans = 0;
            rep (i, 1, n) cin >> a[i], f[i] = 0;
            rep (i, 1, n) ans = max(ans, dp(i));
            cout << ans << '
    ';
        }
        return 0;
    }
    

    C

    自己写写画画, 会发现对于答案的每个因子

    必定是 a[1] ~ a[n] 中 n或(n-1)个数的因子, 否则答案不可能含有这个因子

    所以简单了

    先枚举a[1]的所有因子, 看看其他数时候含有这个因子(最多一个数没有), 则这个因子必定出现在答案中, 其他数将这个因子除去

    然后再枚举a[2]的所有因子, 这次其他的(a[1]除外)数必须都有这个因子(a[1]没有, 如果a[1]有, 再第一次循环就已经除掉了), 操作同上

    再加点细节优化, 就水过了

    记得特判

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
     
    const int maxn = 1e5 + 5;
     
    int n, m, _, ans = 1, res = 1;
    int a[maxn];
     
    bool work(int k, int d, int z)
    {
        int flag = 0;
        rep (j, k + 1, n)
        {
            if (res != 1 && a[j] % res == 0) a[j] /= res;
            if (flag > z) continue;
            if (a[j] % d && flag <= z) ++flag;
            if (flag > z && res == 1) break;
        }
     
        res = 1; 
        if (flag <= z) ans *= d, res = d; 
        return (res != 1);
    }
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        cin >> n; 
        rep (i, 1, n) cin >> a[i];
        sort(a + 1, a + 1 + n);
            
        if (n == 2) { cout << ((ll)a[1] * a[2] / __gcd(a[1], a[2])); return 0; }
     
        for (int i = 2; i <= a[1]; ++i)
        {
            if (a[1] % i) continue;
            if (work(1, i, 1)) a[1] /= i, --i;
        }
     
        for (int i = 2; i <= a[2]; ++i)
        {
            if (a[2] % i) continue;
            if (work(2, i, 0)) a[2] /= i, --i;
        }
     
        cout << ans;
        return 0;
    }
    
    

    D

    小细节特判直接看代码,主要说思路

    1.对于两个相邻的数 a[x] <= a[y], 则可以将 a[y] 变为 a[x], 然后整个序列就会都可以改成a[x]

    2.对于三个相邻的数 a[j] >= k && a[j + 2] >= k 则 a[j],a[j + 1], a[j + 2]都可以变为一个 >= k的数, 然后覆盖整个序列

    所以问题变成了, 是否可以将 a[i] == k 两边的 a[i - 1] 和 a[i + 1] 变为 >= k

    找存在 a[i] >= k 且 a[i + 2] >= k , 或者 a[i] >= k 且 a[i + 1] >= k 就 "YES"

    记得特判特殊情况就行

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
    
    const int maxn = 1e5 + 5;
    
    int n, m, _;
    int a[maxn];
    
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            cin >> n >> m;
            int flag = 0, f = 0; 
    
            rep (i, 1, n)
            {
                cin >> a[i];
                if (a[i] == m) ++f;
                if (flag) continue;
                if (i > 1 && a[i] >= m && a[i - 1] >= m) flag = 1;
                if (i > 2 && a[i] >= m && a[i - 2] >= m) flag = 1;
            }
    
            if (n == 1 && a[1] == m) flag = 1;
            
            if (flag && f) cout << "YES
    ";
            else cout << "NO
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    SqlLite的使用
    asp.net批量上传图片带进度条显示
    对于GridView控件的RowDataBount事件的错误理解
    关于SQL中时间对比
    关于使用触发器时使用@@identity的问题
    关于Treeview控件如何给每个节点加js脚本的方法
    /etc/init.d/functions详解
    如何解决安装DreamWeaver8 时候提示“无法将数值写入键/SOFTWARE/classes/.shtml”
    [请教]关于超大数据量网站的数据搜索和分页的实现方法
    svchost.exe[900]中发生未处理的win32异常
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/12885307.html
Copyright © 2011-2022 走看看