コンテスト1000年

A:貪欲。一つは、文字列テンプレートの文字列に一致することができるであろうようにので、複数の文字は、変更することができます。数は、文字列を直接直接一致または支出の時間変化に合わせ、前方のマップテンプレート文字列を入れたものを覚えておいてください。

#include<bits/stdc++.h>
using namespace std;
#define For(i,x,y)for(i=x;i<=y;i++)
map<string,int>mp;
string str;
int main()
{
    int s,n,i;
    cin>>n;
    s=n;
    For(i,1,n)
    {
        cin>>str;
        if(!mp.count(str))mp[str]=1;
        else mp[str]++;
    }
    For(i,1,n)
    {
        cin>>str;
        if(mp.count(str)&&mp[str])s--,mp[str]--;
    }
    cout<<s;
    return 0;
}
/*3
XS
XX
M
XS
XS
M*/

B:また、2つのランプはこの状態を変更列挙それらの間の時間と時間のオンとオフの統計サフィックスターンを、ランプの状態を変更します後ろランプの状態を変更することは明らかです。これは2つの選択肢があり、いずれかの一時一定時間ノードの直後に変化したとき、または接合前に一定時間の変化、より良好になるために移動させることができる2つの点の間の時間がなければなりません。

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define Max(x,y)(x>y?x:y)
#define For(i,x,y)for(i=x;i<=y;i++)
#define Down(i,x,y)for(i=x;i>=y;i--)
int tim[N][2],a[N];
int main()
{
    int n,m,i,mx;
    scanf("%d%d",&n,&m);
    For(i,1,n)scanf("%d",&a[i]);
    a[n+1]=m;
    Down(i,n,0)
    {
        tim[i][1]=tim[i+1][1];
        //关灯时间 
        tim[i][0]=tim[i+1][0];
        //开灯时间 
        tim[i][i&1]+=a[i+1]-a[i];
    }
    /*printf("%d",tim[0][0]);*/
    mx=/*0*/tim[0][0];
    Down(i,n,0)
    {
        if(a[i+1]>a[i]+1)mx=Max(mx,tim[i][1]+tim[0][0]-tim[i][0]+(i&1?-1:1));
        if(a[i+1]>a[i]+1)mx=Max(mx,tim[i+1][1]+tim[0][0]-tim[i+1][0]+(i&1?1:-1));
    }
    printf("%d",mx);
    return 0;
}

データの唯一最大の範囲は小さな違いから直接することができた場合は、実際には、多くの場所は、役に立たない場所が変更されているがあり、私たちの違いの進路を考える:C (2N \)\、隣接する二つの位置の間の値変わらず。だから、差をシミュレートすることができるシーケンスの最後の行を引き出し、そして毎回統計答え。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 400005
#define For(i,x,y)for(i=x;i<=y;i++)
struct line
{
    ll w;
    int v;
}p[N];
ll ans[N];
ll read()
{
    ll A;
    bool K;
    char C;
    C=A=K=0;
    while(C<'0'||C>'9')K|=C=='-',C=getchar();
    while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar();
    return(K?-A:A);
}
void write(ll X)
{
    if(X<0)putchar('-'),X=-X;
    if(X>9)write(X/10);
    putchar(X%10|48);
}
inline bool cmp(line _,line __)
{
    return _.w<__.w;
}
int main()
{
    ll l,r;
    int n,i,cnt,now;
    n=read();
    now=cnt=0;
    For(i,1,n)
    {
        l=read(),r=read();
        p[++cnt].w=l;
        p[cnt].v=1;
        p[++cnt].w=r+1;
        p[cnt].v=-1;
    }
    sort(p+1,p+cnt+1,cmp);
    now=p[1].v;
    For(i,2,cnt)ans[now]+=p[i].w-p[i-1].w,now+=p[i].v;
    For(i,1,n)write(ans[i]),putchar(' ');
    return 0;
}

D:転送するために、第1のフリップフロッアレイ。セット\(のf_i \)セクションで表現(I \)\良いシーケンスの数で終わるシリアル番号は、列挙された\(J \) \(jは\)良いの良いの戦いのシーケンスの最後に配列、乗算して乗算の原理に従って。組合せの数によって良好なアレイ・カウントの数、(IJ-1 \)\に番号を選択する\(a_iを\)番目(\(I \)番号が選択されています)。最終累積覚えておいてください\(F \)の配列を。

#include<bits/stdc++.h>
using namespace std;
#define N 1005
#define Mod 998244353
#define For(i,x,y)for(i=x;i<=y;i++)
#define Down(i,x,y)for(i=x;i>=y;i--)
int fac[N],inv[N],a[N],f[N];
namespace BASICMATH
{
    inline void inc(int&x,int y)
    {
        x=(x+y)%Mod;
    }
}
using namespace BASICMATH;
int ksm(int x,int y)
{
    if(!y)return 1;
    return 1LL*ksm(1LL*x*x%Mod,y>>1)*(y&1?x:1)%Mod;
}
int C(int x,int y)
{
    if(y>x)return 0;
    return 1LL*fac[x]*inv[y]%Mod*inv[x-y]%Mod;
}
int main()
{
    int n,i,j,tot=0;
    cin>>n;
    fac[1]=1;
    For(i,2,n)fac[i]=1LL*fac[i-1]*i%Mod;
    inv[n]=ksm(fac[n],Mod-2);
    Down(i,n-1,0)inv[i]=1LL*inv[i+1]*(i+1)%Mod;
    For(i,1,n)cin>>a[n-i+1];
    f[0]=1;
    //基数 
    For(i,1,n)
    {
        if(a[i]>0)
        For(j,0,i-a[i]-1)inc(f[i],1LL*f[j]*C(i-j-1,a[i])%Mod);
        //强制选取i 
        inc(tot,f[i]);
    }
    cout<<tot;
    return 0;
}
/*4
2 2 1 1*/

おすすめ

転載: www.cnblogs.com/May-2nd/p/12505762.html
おすすめ