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

 

posted @ 2017-04-18 17:52  zzzzzzzzhu  阅读(222)  评论(0编辑  收藏  举报