Codeforces 补题 round 1 contest 797

本文解析了四个算法问题:质因子分解、奇数求和、最小字符串构建及数组查询,并提供了详细的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. k-Factorization

质因子分解,统计一下即可。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define clr(a) memset(a,0,sizeof(a))

const LL MAXN = 1e5+10;
const LL INF = 0x3f3f3f3f;

LL n,k;
LL a[MAXN];
LL num;
void Eular(LL n){
    num = 0;
    clr(a);
    for(LL i=2;i*i<=n;i++){
        while(n%i==0){
            a[num] = i;
            num++;
            n /= i;
        }
    }
    if(n != 1)  num++;
}

int main(){
    while(scanf("%d%d",&n,&k)!=EOF){
        Eular(n);
        LL ans = 1;
        if(num >= k) {
            for(LL i=0;i<k-1;i++){
                printf("%d ",a[i]);
                ans *= a[i];
            }
            printf("%d\n",n/ans);
        }
        else cout<<"-1"<<endl;
    }
    return 0;
}

B. Odd sum

模拟即可

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define clr(a) memset(a,0,sizeof(a))

const int MAXN = 1e5+10;
const int INF = 0x3f3f3f3f;

int n;
int a[MAXN];
int b[MAXN],c[MAXN];
int n1,n2;
int sum ;
bool cmp(int a,int b){
    return a > b;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        if(a[i] > 0)  {
            b[n1++] = a[i];
            sum += a[i];
        }
        else if(a[i] < 0) c[n2++] = -a[i];
    }
    if(sum % 2 == 1)    cout<<sum<<endl;
    else{
        int flag1 = 0,flag2 = 0;
        sort(b,b+n1);
        sort(c,c+n2);
        int x = INF , y = INF ;
        for(int i=0;i<n1;i++){
            if(b[i]%2 == 1){
                x = min(x,b[i]);
                break;
            }
        }
        if(x == INF) flag1 = 1;
        for(int i=0;i<n2;i++){
            if(c[i] %2 == 1){
                y = min(c[i],y);
                break;
            }
        }
       // cout<<sum<<endl;
        if(y == INF ) flag2 = 1;
        int ans;
        //cout<<x <<"   "<<y<<endl;
        if(flag1== 1) ans = sum - y;
        else if(flag2 == 1) ans = sum - x;
        else ans = max(sum - x,sum - y);
        cout<< ans <<endl;
    }
    return 0;
}

C. Minimal string

倒序维护最小的字符 ,每次与栈顶元素比较。若栈顶元素小则出栈输出,否则,新元素入栈。
 

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define clr(a) memset(a,0,sizeof(a))

const int MAXN = 1e5+10;
const int INF = 0x3f3f3f3f;

char s[MAXN],minn[MAXN];

int main(){
    scanf("%s",s);
    int len = strlen(s);
    for(int i=len-1;i>=0;i--){
        if(i == len - 1) minn[i] = s[i];
        else minn[i] = min(minn[i+1],s[i]);
    }
    stack<char>st;
    char top;
    for(int i=0;i<len;i++){
        if(st.empty())
            st.push(s[i]);
        else{
            while(!st.empty()){
                top = st.top();
                if(top <= minn[i]){
                    st.pop();
                    printf("%c",top);
                }
                else    break;
            }
            st.push(s[i]);
        }
    }
    while(!st.empty()){
        top = st.top();
        printf("%c",top);
        st.pop();
    }
    return 0;
}

E - Array Queries

部分dp

当k值较大的时候,我们暴力就可以,反而dp会浪费时间,WA了好多发,取临界值为410。k<=400时用dp直接将结果达成表,

k>400时我们直接暴力。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define clr(a) memset(a,0,sizeof(a))

const int MAXN = 1e5+10;
const int INF = 0x3f3f3f3f;
const int N = 410;
int n,p,k,q;
int a[MAXN];
int dp[MAXN][N];

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    scanf("%d",&q);
    for(int i=n;i>=1;i--){
        for(int j=0;j < N;j++){
            if(a[i] + i + j > n) dp[i][j] = 1;
            else dp[i][j] = dp[a[i] + i + j][j] + 1;
        }
    }
    while(q--){
        scanf("%d%d",&p,&k);
        if(k > N - 10){
            int num = 0;
            while(p <= n){
                p = p + k + a[p];
                num ++;
            }
            printf("%d\n",num);
        }
        else    printf("%d\n",dp[p][k]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值