2022牛客五一集训派对day4(A、E、J)

本文详细解析了牛客网2022五一集训派对第四天的编程竞赛题目,包括J题的Fraction Comparision,比较分数的大小;A题的Equivalent Prefixes,寻找最大区间使得所有子区间最小值下标相等;E题的ABBA,计算满足特定条件的字符串组合数。通过分析思路和提供代码实现,帮助读者理解解题方法。

J、Fraction Comparision

链接:https://ac.nowcoder.com/acm/contest/33552/J
来源:牛客网
题目:
Bobo has two fractions a/x and b/y. He wants to compare them. Find the result.
题意:
比较a/x和b/y的大小
思路:
分子分母想成比较,注意c++会炸ull
代码:

while 1:
    try:
        x,a,y,b=input().split()
        x = int(x)
        y = int(y)
        a = int(a)
        b = int(b)
        if x*b==y*a:
            print("=")
        elif x*b<y*a:
            print("<")
        else:
            print(">")
    except:
        break

A、Equivalent Prefixes

链接:https://ac.nowcoder.com/acm/contest/33552/A
来源:牛客网
题意:
找一个区间[1,q]使得所有子区间的最小值下标相等,输出q的最大值。
思路:
a,b同时维护每个位置的上一个比它小的位置,如果a,b的第i个位置的上个比它小的位置不同时,答案就是i-1,不然一直往后找如果全成立就输出n。接下来就是如何维护,开两个维护小值的单调栈,如果两个栈里面的元素个数不同的话就代表当前位置的上个比它小的位置不同。
代码:

#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
#define int ll
#define pii pair<int,int>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const double pi=acos(-1.0);
const double eps=1e-8;
const int mod=998244353;
const int INF=0x3f3f3f3f;
const int LINF=0x3f3f3f3f3f3f3f3f;
const int MAXN=1e6+10;
int a[MAXN];
int b[MAXN];
int n;
stack<int>aa;
stack<int>bb;
void solve()
{
    while(cin>>n)
    {
        while(!aa.empty())
            aa.pop();
        while(!bb.empty())
            bb.pop();
        for(int i=1; i<=n; ++i)
            cin>>a[i];
        for(int i=1; i<=n; ++i)
            cin>>b[i];
        int ans=n;
        for(int i=1; i<=n; ++i)
        {
            while(!aa.empty()&&aa.top()>a[i])
                aa.pop();
            aa.push(a[i]);
            while(!bb.empty()&&bb.top()>b[i])
                bb.pop();
            bb.push(b[i]);
            if(aa.size()!=bb.size())
            {
                ans=i-1;
                break;
            }
        }
        cout<<ans<<"\n";
    }
}
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int _=1;
    //cin>>_;
    for(int i=1; i<=_; ++i)
    {
        solve();
    }
    return 0;
}
/*

*/

E、ABBA

链接:https://ac.nowcoder.com/acm/contest/33552/E
来源:牛客网
题意:
一个长度为2*(n+m)的字符串分解成n个AB子序列和m个BA子序列,问有多少种字符串满足条件
思路:
设dp[i][j]代表i个A和j个B的情况下的种类数,我们可以确定的是第i+j+1个位置一定是A或者B,由此可知dp[i+1][j]+=dp[i][j],dp[i][j+1]+=dp[i][j],但是有两个限制AB串是n个,BA串是m个所以当第i+j+1个位置填入的是A的情况下我们要保证i-j+1<=n(前i个A和j个B组合一定会有i-j个A被剩下再加上当前的位置是A所以会有i-j+1个A即最后会最少出现i-j+1个AB),同理BA。
代码:

#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
#define int ll
#define pii pair<int,int>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const double pi=acos(-1.0);
const double eps=1e-8;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int LINF=0x3f3f3f3f3f3f3f3f;
const int MAXN=1e6+10;
int dp[2005][2005];
void solve()
{
    int n,m;
    while(cin>>n>>m)
    {
        for(int i=0; i<=n+m; ++i)
        {
            for(int j=0; j<=n+m; ++j)
            {
                dp[i][j]=0;
            }
        }
        dp[0][0]=1;
        for(int i=0; i<=n+m; ++i)
        {
            for(int j=0; j<=n+m; ++j)
            {
                if(i-j+1<=n)
                {
                    dp[i+1][j]+=dp[i][j];
                    dp[i+1][j]%=mod;
                }
                if(j-i+1<=m)
                {
                    dp[i][j+1]+=dp[i][j];
                    dp[i][j+1]%=mod;
                }
            }
        }
        cout<<dp[n+m][n+m]<<"\n";
    }
}
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int _=1;
    //cin>>_;
    for(int i=1; i<=_; ++i)
    {
        solve();
    }
    return 0;
}
/*
4e3
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值