牛客練習賽51 題解 ABCDE

A B C都是水題。

C要講一下

C 原題鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6441

題解講的很明白了:

A

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e5+10;
ll dp[N][4];
char s[N];
int main()
{
    cin>>s+1;
    int n=strlen(s+1);
    for(int i=1;i<=n;++i)
    {
        if(s[i]=='a')
        {
            dp[i][1]=dp[i-1][1]+1;
            dp[i][2]=dp[i-1][2];
            dp[i][3]=dp[i-1][3];
        }
        else if(s[i]=='b')
        {
 
            dp[i][1]=dp[i-1][1];
            dp[i][2]=dp[i-1][2]+dp[i-1][1];
            dp[i][3]=dp[i-1][3];
            //printf("i:%d %d\n",i,dp[i][2]);
        }
        else if(s[i]=='c')
        {
            dp[i][1]=dp[i-1][1];
            dp[i][2]=dp[i-1][2];
            dp[i][3]=dp[i-1][3]+dp[i-1][2];
        }
        else{
            dp[i][1]=dp[i-1][1];
            dp[i][2]=dp[i-1][2];
            dp[i][3]=dp[i-1][3];
        }
    }
    //rep(i,1,n) printf("%lld %lld %lld\n",dp[i][1],dp[i][2],dp[i][3]);
    printf("%lld\n",dp[n][3]);
}

B

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps=1.0e-5;
const int maxn=1000000+10;
const ll mod=1e9+7;
int m,n,t;
char a[maxn],b[maxn];
int nxt[maxn][30];
 
int main()
{
    int n,t;
    cin>>n>>t;
    scanf("%s",a+1);
    for(int i=n;i>=1;i--)
    {
        for(int j=0;j<=25;j++) nxt[i-1][j]=nxt[i][j];
        nxt[i-1][a[i]-'a']=i;
    }
    while(t--)
    {
        scanf("%s",b+1);
        m=strlen(b+1);
        int flag=0;
        bool flg=true;
        for(int i=1;i<=m;i++)
        {
            flag=nxt[flag][b[i]-'a'];
            if(flag==0){
                puts("NO");
                flg=false;
                break;
            }
        }
        if(flg) puts("YES");
        //printf("III\n");
    }
}

C 按照題解公式化簡求答案即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll n;
    cin>>n;
    if(n==1||n==2)
    {
        printf("-1");
        return 0;
    }
    ll b,c;
    if(n%2==1)
    {
        b=(n*n-1)/2;
        c=b+1;
    }
    else{
        b=(n*n-4)/4;
        c=b+2;
    }
    printf("%lld %lld",b,c);
}

D 題解說是二分圖或最大流

但我是瞎搞過的。保存每個座標被覆蓋的區間,然後查詢的枚舉這些座標的區間即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
const int N=1000;
struct node
{
    int l,r;
    bool operator<(const node&o)
    {
        return r<o.r;
    }
}a[N];
int n,q;
vector<int>G[N];
bool vis[N];
int main()
{
    cin>>n>>q;
    rep(i,1,n) scanf("%d",&a[i].l);
    rep(i,1,n) scanf("%d",&a[i].r);
    sort(a+1,a+1+n);
    //rep(i,1,n) printf("%d %d\n",a[i].l,a[i].r);
    rep(i,1,n)
    {
        for(int j=a[i].l;j<=a[i].r;++j)
        {
            G[j].push_back(i);
        }
    }
    while(q--)
    {
        int ql,qr;
        scanf("%d%d",&ql,&qr);
        int id=ql;
        int ans=0;
        rep(i,1,n) vis[i]=0;
        while(id<=qr)
        {
            for(int i:G[id])
            {
                if(vis[i]) continue;
                if(a[i].l<=id&&id<=a[i].r) {
                    ans++;
                    vis[i]=1;
                    break;
                }
            }
            id++;
        }
        printf("%d\n",ans);
    }
}

E

其實就是構造一個數列是,1234123123.。。從1到4,或者是1到3.可以二分這個4,也可以二分分成了多少段。兩者均可以通過公式轉換一下。

那麼題解有用的部分就是下面這一段:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m;
bool cal(ll mi)
{
    return (n/mi+1)*(n/mi+2)/2*(n%mi)+(n/mi)*(n/mi+1)/2*(mi-n%mi)<=m;
}
int main()
{
    cin>>n>>m;
    ll l=1,r=n;
    ll ans=-1;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(cal(mid))
        {
            ans=mid,r=mid-1;
        }
        else l=mid+1;
    }
    //printf("ans:%lld\n",ans);
    for(int i=1;i<=n%ans;++i)
    for(int j=1;j<=n/ans+1;++j) printf("%d ",j);

    for(int i=1;i<=ans-n%ans;++i)
    for(int j=1;j<=n/ans;++j) printf("%d ",j);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章