奋斗群群赛---8

奋斗群群赛—8

T1:k-Factorization

题目位置:

T1位置所在

题意:

给你一个数字n与m,能输出将n分解为m个大于1的数的乘积,输出其中的一种就好!
不能就输出-1来表示不行

AC代码:

#include <bits/stdc++.h>
using namespace std;
int k1[100005];
int f(int x)
{
    for(int i=2; i<=x; i++)
        if(x%i==0)
            return i;
}
int main()
{
    int n,k,tot=0;
    cin>>n>>k;

    while(tot!=k-1&&n!=1)
    {
        k1[tot]=f(n);
        n/=f(n);
        tot++;
    }
    if(tot==k-1&&n!=1)
    {
        for(int i=0; i<tot; i++)
            cout<<k1[i]<<" ";
        cout<<n;
    }
    else
    {
     cout<<-1;
    }
}

小反思:

无,只要稍微想想就好了!

T2:Odd sum

题目位置:

T2题目所在

题意:

给你n个数字,求一个子集,使得子集内部的和为奇数而且值是最大的,输出这个值

AC代码:

#include <bits/stdc++.h>
using namespace std;
int a[100005];
int main()
{
    int n,inf=999999;
    long long int tot=0;
    scanf("%d",&n);

    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]>=0)
            tot+=a[i];
    }
    if(tot%2==1)
    {
        cout<<tot<<endl;
        return 0;
    }
    else
    {
        for(int i=1; i<=n; i++)
            if(abs(a[i])<inf&&abs(a[i])%2==1)
                inf=abs(a[i]);
        cout<<tot-inf;
    }
    return 0;
}

T3:Minimal string

题目位置:

T3题目所在

题意:

意思简单点就是一个字符串s,利用一个栈来使得这个新的字符串的字典序最小,求着个字符串.其实一开始就要预处理,预处理什么呢?就是在第i位,输出i~n位的字符串中的最小的字符就好了!那么有人会问:要不要全盘扫啊?其实不需要的,只要从n开始–来比较相邻的就可以了!

m[len]=inf;
    for(int i=len-1; i>=0; i--)
    {
        m[i]=min(m[i+1],s[i]);
    }

AC代码:

手写栈的程序:

#include <bits/stdc++.h>
using namespace std;

const int MAX=100100;
const int inf='z'+1;
char s[MAX],t[MAX],m[MAX];
int main()
{

    string s;
    cin>>s;
    int len=s.length();

    m[len]=inf;
    for(int i=len-1; i>=0; i--)
    {
        m[i]=min(m[i+1],s[i]);
    }
    int j=0;
    for(int i=0; i<len; i++)
    {
        t[j]=s[i];
        j++;
        while(j>0&&t[j-1]<=m[i+1])
        {
            cout<<t[--j];
        }
    }
    return 0;
}

系统自带栈的程序:

#include <bits/stdc++.h>
#include <stack>
using namespace std;
const int MAX=100100;
const int inf='z'+1;
char s[MAX],t[MAX],m[MAX];
stack <int> my_stack;
int main()
{
    string s;
    cin>>s;

    int len=s.length();
    m[len]=inf;
    for(int i=len-1;i>=0;i--)
    {
        m[i]=min(m[i+1],s[i]);
    }
    int p=0;
    while(my_stack.empty()==0||p<len)
    {
        while(my_stack.empty()==0&&my_stack.top()<=m[p])
        {
        cout<<(char)my_stack.top();
        my_stack.pop();
        }
        if(len==p) break;
        my_stack.push(s[p]);
        p++;
    }
}

T4:Broken BST

题目位置:

T4位置所在

题意:

AC代码:

T5:Array Queries

题目位置

T5位置所在

题意:

有n个整数,有这样的询问,给你m个询问,每个询问有2个数,分别为p,k.
有这样的while循环,p=p+a[p]+k;直到p>n为止,然后输出了次数,求其值!
其实仔细想就会发现k是影响较大的数字,如果k小的话,就会导致while循环执行了太多的次数了,所以不怕k的值大,就怕k小!,所以要预处理k小的值!
dp为:

for(int k=1; k<=line; k++)
        for(int i=n; i>=1; i--)
        {
            if(k+a[i]+i>n)
                f[k][i]=1;
            //cout<<f[i][j];
            else          //p=p+k+a[p]  i->p
            {
                int r=i+k+a[i];
                f[k][i]=f[k][r]+1;
            }
        }

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int line=500,N=100005;
int a[N],f[505][N];
int main()
{
    //k 1~line up!
    int n,m,x,k1;
    scanf("%d",&n);

    for(int i=1; i<=n; i++)
        scanf("%d",&a[i]);
    //´Ómax¿ªÊ¼ÏòÏÂ--;  //ö¾Ù+1¾ÍºÃ!!!

    for(int k=1; k<=line; k++)
        for(int i=n; i>=1; i--)
        {
            if(k+a[i]+i>n)
                f[k][i]=1;
            //cout<<f[i][j];
            else          //p=p+k+a[p]  i->p
            {
                int r=i+k+a[i];
                f[k][i]=f[k][r]+1;
            }
        }

    scanf("%d",&m);
    for(int v=1; v<=m; v++)
    {
        scanf("%d%d",&x,&k1);
        int time=0,p=x;
        if(k1<=line)
        {
            cout<<f[k1][x]<<endl;

            continue;
        }
        else
            while(p<=n)
            {
                p=p+a[p]+k1;
                time++;
            }
        cout<<time<<endl;
    }
    return 0;
}

总结:

1.善于预处理
2.发现简单易行的方法!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值