[Codeforces 883D]Packmen Strike Back

本文解析了883D题目,介绍了对于多个P字符的情况如何通过二分查找确定最优解。文章详细阐述了贪心策略,包括判断P字符的方向选择及其条件,并给出了实现代码。

883D

题解:
特殊处理只有一个 P “ P ” 的情况。
对于有两个以上的 P “ P ” ,第一问的答案一定是所有 “ ∗ ” 的个数。
显然第二问的答案具有单调性,所以二分答案,对于一个长度 len l e n ,只要从左到右分配方向分几种情况贪心处理就行了。
贪心策略:
1. 如果当前的 P “ P ” 的左边没有没被覆盖的 “ ∗ ” ,那么方向一定是向右。
2. 如果当前的 P “ P ” 向左并不能覆盖当前没被覆盖的最左边的 “ ∗ ” ,则长度len是不合法的。
3. 如果当前的 P “ P ” 左边的没有其他的 P “ P ” ,或者如果当前的 P “ P ” 向左不能代替前一个 P “ P ” ,则直接把这个 P “ P ” 设定为向左,不改变前面 P “ P ” 的朝向。
4. 如果当前的 P “ P ” 向左能够代替前一个 P “ P ” ,则将前一个 P “ P ” 的方向设置成向右。
5. 如果当前的 P “ P ” 前面一个 P “ P ” 之前执行过 4 4 , 且,当前的P能够替代前一个 P “ P ” ,则将当前的 P “ P ” 朝向设为向左,前一个 P “ P ” 朝向设为向右,前面第二个 P “ P ” 的朝向设为向左。

时间复杂度: O(nlogn) O ( n l o g n )

代码:

#include<bits/stdc++.h>
#define LL long long
#define ull unsigned long long
#define ULL ull
#define mp make_pair
#define pii pair<int,int>
#define piii pair<int, pii >
#define pll pair <ll,ll>
#define pb push_back
#define big 20160116
#define INF 2147483647
#define pq priority_queue
#define rank rk124232
#define y1 y20160116
#define y0 y20160110
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
namespace Mymath{
    LL qp(LL x,LL p,LL mod){
        LL ans=1;
        while (p){
            if (p&1) ans=ans*x%mod;
            x=x*x%mod;
            p>>=1;
        }
        return ans;
    }
    LL inv(LL x,LL mod){
        return qp(x,mod-2,mod);
    }
    LL C(LL N,LL K,LL fact[],LL mod){
        return fact[N]*inv(fact[K],mod)%mod*inv(fact[N-K],mod)%mod;
    }
    template <typename Tp> Tp gcd(Tp A,Tp B){
        if (B==0) return A;
        return gcd(B,A%B);
    }
    template <typename Tp> Tp lcm(Tp A,Tp B){
        return A*B/gcd(A,B);
    }
};
namespace fwt{
    using namespace Mymath;
    void FWT(int a[],int n,LL mod)
    {
        for(int d=1;d<n;d<<=1)
            for(int m=d<<1,i=0;i<n;i+=m)
                for(int j=0;j<d;j++)
                {
                    int x=a[i+j],y=a[i+j+d];
                    a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                    //xor:a[i+j]=x+y,a[i+j+d]=x-y;
                    //and:a[i+j]=x+y;
                    //or:a[i+j+d]=x+y;
                }
    }

    void UFWT(int a[],int n,LL mod)
    {
        LL rev=inv(2,mod);
        for(int d=1;d<n;d<<=1)
            for(int m=d<<1,i=0;i<n;i+=m)
                for(int j=0;j<d;j++)
                {
                    int x=a[i+j],y=a[i+j+d];
                    a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
                    //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
                    //and:a[i+j]=x-y;
                    //or:a[i+j+d]=y-x;
                }
    }
    void solve(int a[],int b[],int n,LL mod)
    {
        FWT(a,n,mod);
        FWT(b,n,mod);
        for(int i=0;i<n;i++) a[i]=1LL*a[i]*b[i]%mod;
        UFWT(a,n,mod);
    }
};
const int Maxn=1e6+5;
int n;
char c[Maxn];
int ppos[Maxn],kp;
int apos[Maxn],ka;
int dir[Maxn];// 1:right -1:left 2: right(const) -2:left(have ancestor)
int fc[Maxn];
int fc2[Maxn];
bool check(int l){
    ka=kp=0;
    for (int i=0;i<n;i++){
        if (c[i]=='P'){
            ppos[kp++]=i;
        }
    }
    for (int i=0;i<n;i++){
        if (c[i]=='*'){
            apos[ka++]=i;
        }
    } 
    int nowgt=0;
    for (int i=0;i<kp;i++){
        //cout<<i<<' '<<nowgt<<endl;
        if (ppos[i]<apos[nowgt]){
            dir[i]=2;
            while (nowgt<ka && ppos[i]+l>=apos[nowgt]) nowgt++;
            if (nowgt==ka) return true;
        }
        else{
            if (ppos[i]-l>apos[nowgt]) return false;
            if (i==0){
                dir[i]=-1;
                fc[i]=nowgt;
                while (nowgt<ka && ppos[i]>=apos[nowgt]) nowgt++;
                if (nowgt==ka) return true;
                continue;
            }
            if (dir[i-1]==-1){
                int xp=apos[fc[i-1]];
                if (ppos[i]-l<=xp){
                    dir[i-1]=1;
                    dir[i]=-2;
                    fc2[i]=nowgt;
                    while (nowgt<ka && ppos[i-1]+l>=apos[nowgt]) nowgt++;
                    if (nowgt==ka) return true;
                    fc[i]=fc[i-1];
                }
                else{
                    fc[i]=nowgt;
                    dir[i]=-1;
                    while (nowgt<ka && ppos[i]>=apos[nowgt]) nowgt++;
                    if (nowgt==ka) return true;
                }
            }
            else if (dir[i-1]==-2){
                int xp=apos[fc[i-1]];
                if (ppos[i]-l<=xp){
                    dir[i-1]=1;
                    dir[i]=-2;
                    fc2[i]=nowgt;
                    while (nowgt<ka && ppos[i-1]+l>=apos[nowgt]) nowgt++;
                    if (nowgt==ka) return true;
                    fc[i]=fc[i-1];
                }
                else{
                    xp=apos[fc2[i-1]];
                    if (ppos[i]-l<=xp){
                        dir[i-2]=-1;
                        dir[i-1]=1;
                        dir[i]=-2;
                        fc2[i]=nowgt;
                        fc[i]=fc[i-1];
                        while (nowgt<ka && ppos[i-1]+l>=apos[nowgt]) nowgt++;
                        if (nowgt==ka) return true;
                    }
                    else{
                        fc[i]=nowgt;
                        dir[i]=-1;
                        while (nowgt<ka && ppos[i]>=apos[nowgt]) nowgt++;
                        if (nowgt==ka) return true;
                    }
                }
            }
            else{
                fc[i]=nowgt;
                dir[i]=-1;
                while (nowgt<ka && ppos[i]>=apos[nowgt]) nowgt++;
                if (nowgt==ka) return true;
            }
        }
    }
    return false;
}
int main(){
    scanf("%d",&n);
    scanf("%s",c);
    int cnt=0;
    int pos;
    int ca=0;
    for (int i=0;i<n;i++){
        if (c[i]=='P') cnt++,pos=i;
        if (c[i]=='*') ca++;
    }
    if (cnt==1){
        int c1=0,c2=0;
        int l=n,r=-1;
        for (int i=0;i<pos;i++){
            if (c[i]=='*') c1++,l=min(l,i);
        }
        for (int i=pos+1;i<n;i++){
            if (c[i]=='*') c2++,r=max(r,i);
        }
        if(c1>c2){
            printf("%d %d\n",c1,pos-l);
        }
        else if (c2>c1){
            printf("%d %d\n",c2,r-pos);
        }
        else{
            printf("%d %d\n",c1,min(pos-l,r-pos));
        }
        return 0;
    }
    //cerr<<123<<endl;
    printf("%d ",ca);
    int lo=0,hi=n;
    while (hi-lo>1){
        int mid=lo+hi>>1;
        if (check(mid)){
            hi=mid;
        }
        else{
            lo=mid;
        }
    }
    printf("%d\n",hi);
}
/*
6
*.P*P*
*/ 
### Codeforces 1487D Problem Solution The problem described involves determining the maximum amount of a product that can be created from given quantities of ingredients under an idealized production process. For this specific case on Codeforces with problem number 1487D, while direct details about this exact question are not provided here, similar problems often involve resource allocation or limiting reagent type calculations. For instance, when faced with such constraints-based questions where multiple resources contribute to producing one unit of output but at different ratios, finding the bottleneck becomes crucial. In another context related to crafting items using various materials, it was determined that the formula `min(a[0],a[1],a[2]/2,a[3]/7,a[4]/4)` could represent how these limits interact[^1]. However, applying this directly without knowing specifics like what each array element represents in relation to the actual requirements for creating "philosophical stones" as mentioned would require adjustments based upon the precise conditions outlined within 1487D itself. To solve or discuss solutions effectively regarding Codeforces' challenge numbered 1487D: - Carefully read through all aspects presented by the contest organizers. - Identify which ingredient or component acts as the primary constraint towards achieving full capacity utilization. - Implement logic reflecting those relationships accurately; typically involving loops, conditionals, and possibly dynamic programming depending on complexity level required beyond simple minimum value determination across adjusted inputs. ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; vector<long long> a(n); for(int i=0;i<n;++i){ cin>>a[i]; } // Assuming indices correspond appropriately per problem statement's ratio requirement cout << min({a[0], a[1], a[2]/2LL, a[3]/7LL, a[4]/4LL}) << endl; } ``` --related questions-- 1. How does identifying bottlenecks help optimize algorithms solving constrained optimization problems? 2. What strategies should contestants adopt when translating mathematical formulas into code during competitive coding events? 3. Can you explain why understanding input-output relations is critical before implementing any algorithmic approach? 4. In what ways do prefix-suffix-middle frameworks enhance model training efficiency outside of just tokenization improvements? 5. Why might adjusting sample proportions specifically benefit models designed for tasks requiring both strong linguistic comprehension alongside logical reasoning skills?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值