zoukankan      html  css  js  c++  java
  • Codeforces_797

    学了一学期还是那么菜。

    好久没更新,还是得放点东西的。


    A.贪心最小的素因子,k = 1时,直接输出n就可以了。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,k;
    vector <int> ans;
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n >> k;
        int cnt = 0;
        if(k == 1)
        {
            cout << n <<endl;
            return 0;
        }
        for(int i = 2;i <= n;i++)
        {
            while(n%i == 0)
            {
                ans.push_back(i);
                n /= i;
                cnt++;
                if(cnt == k-1 && n > 1 || cnt == k && n == 1)
                {
                    for(int j = 0;j < ans.size();j++)   cout << ans[j] << " ";
                    if(n > 1)   cout  << n;
                    return 0;
                }
            }
        }
        cout << -1 << endl;
        return 0;
    }
    View Code

    B.偶数大于0的全加,奇数排序一下,贪心最大的奇数个数的奇数和。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,a[100005];
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        long long ans = 0;
        int cnt = 0;
        for(int i = 1;i <= n;i++)
        {
            int x;
            cin >> x;
            if(x%2 == 0 && x > 0)       ans += x;
            else if(x%2)    a[++cnt] = x;
        }
        sort(a+1,a+1+cnt);
        ans += a[cnt];
        for(int i = cnt-1;i >= 1;i -= 2)
        {
            if(i-1 < 1) break;
            if(a[i]+a[i-1] > 0) ans += a[i]+a[i-1];
        }
        cout << ans << endl;
        return 0;
    }
    View Code

    C.记录出现的字母,起始点为字符串首s,每次操作选下一个出现过的最小的字符c,终点为最后一个该字符的位置e,若s<e,则将该段的字符一个个入栈(等于c的字符直接输出)。另外,每次选取一个字符时,栈顶比当前字符小或相等的字符要输出。

    #include<bits/stdc++.h>
    using namespace std;
    
    string s;
    int ok[128] = {0};
    stack<char> ss;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> s;
        for(int i = 0;i < s.length();i++)   ok[s[i]] = 1;
        int now = 0;
        for(char i = 'a';i <= 'z';i++)
        {
            if(!ok[i])  continue;
            while(!ss.empty() && ss.top() <= i)
            {
                cout << ss.top();
                ss.pop();
            }
            int t = s.length()-1;
            while(s[t] != i)    t--;
            while(now <= t)
            {
                if(s[now] == i) cout << i;
                else ss.push(s[now]);
                now++;
            }
        }
        while(!ss.empty())
        {
            cout << ss.top();
            ss.pop();
        }
        cout << endl;
        return 0;
    }
    View Code

    D.map记录每个数及个数,dfs判断点,每次更新判断区间,若符合,则当前点的值对应的value置为0,最后把每个值的value加起来就可以了。代码写麻烦了,不必要建树的。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,a[100005],l[100005],r[100005],vis[100005] = {0};
    map<int,int> mp;
    
    struct xx
    {
        int x;
        xx():l(NULL),r(NULL){};
        xx *l,*r;
    }*root;
    
    void insertt(int now,xx *&p)
    {
        p = new xx;
        p->x = a[now];
        if(l[now] > 0)  insertt(l[now],p->l);
        if(r[now] > 0)  insertt(r[now],p->r);
    }
    
    void dfs(xx *p,int ll,int rr)
    {
        if(!p)  return;
        if(ll < p->x && p->x < rr)    mp[p->x] = 0;
        dfs(p->l,ll,min(p->x,rr));
        dfs(p->r,max(p->x,ll),rr);
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        for(int i = 1;i <= n;i++)
        {
            cin >> a[i] >> l[i] >> r[i];
            if(l[i] > 0)    vis[l[i]] = 1;
            if(r[i] > 0)    vis[r[i]] = 1;
            mp[a[i]]++;
        }
        root = NULL;
        for(int i = 1;i <= n;i++)
        {
            if(vis[i])  continue;
            insertt(i,root);
        }
        dfs(root,-2e9,2e9);
        int ans = 0;
        for(map<int,int>::iterator it = mp.begin();it != mp.end();it++) ans += it->second;
        cout << ans << endl;
        return 0;
    }
    View Code

    E.将k分类,k>sqrt(n)时,直接暴力,O(sqrt(n))。其余的k,dp保存答案。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,q,a[100005],dp[100005][355];
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        for(int i = 1;i <= n;i++)   cin >> a[i];
        for(int j = 1;j <= 350;j++)
        {
            for(int i = n;i >= 1;i--)
            {
                if(i+a[i]+j > n)    dp[i][j] = 1;
                else    dp[i][j] = dp[i+a[i]+j][j]+1;
            }
        }
        cin >> q;
        while(q--)
        {
            int p,k;
            cin >> p >> k;
            if(k <= 350)    cout << dp[p][k] << endl;
            else
            {
                int cnt = 0;
                while(p <= n)   p = p+a[p]+k,cnt++;
                cout << cnt << endl;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    作业17
    模块
    Find the Lost Sock (异或算法)
    CD(二分)
    数字流输入
    最大连续子序列(dp)
    STL学习----lower_bound和upper_bound算法
    输入挂(减少时间)
    暴力之全排列
    【C++】判断元素是否在vector中,对vector去重,两个vector求交集、并集
  • 原文地址:https://www.cnblogs.com/zhurb/p/6729119.html
Copyright © 2011-2022 走看看