グリッドを埋める【#589 B Codeforcesラウンド】

トピックリンク

グリッドを充填

導入する

あると仮定\(H×W \)空または完全な細胞からなるグリッド。のは、いくつかの定義を作ってみましょう:

  • \(R_iを\)で左側に接続された連続した完全細胞の数である\(iは\)行目の\((1≤i≤h)\) 特に、\(R_iを= 0 \)の左端のセルならば\(iは\)行目は空です。
  • \(c_j \)に上端に接続された連続した完全細胞の数である\(J \)列目の\((1≤j≤w)\) 特に、\(c_j = 0 \)の一番上のセルならば\(Jの\)番目の列は空です。
    換言すれば、\(iは\)行目は、正確で始まり\(R_iを\)完全細胞。同様に、\(Jの\)列目は、正確で始まり\(c_j \)完全細胞。

    これらは、\(R \)\(C \)いくつかの値\(3×4 \)グリッド。黒セルがいっぱいで、白いセルが空になっています。
    あなたは、の値が持っている\(rは\)\(のC \) 最初は、すべてのセルは空です。値を満たすためにグリッドセルを埋めるために、いくつかの方法下さい\(のR \)とを\(C \) 答えは非常に大きくなる可能性があるので、回答モジュロ見つける\(十億七(10 ^ 9 + 7)\) 換言すれば、によって回答の除算した余りを見つける\(1000000007(10 ^ 9 + 7)\)

    入力

    最初の行は二つの整数含ま\(時間\)\(W \) \((1≤h、w≤10^ 3)\)グリッドの高さと幅を- 。
    2行目は含ま\(時間\)整数\(R_1、R_2、...、R_H(0≤r_i≤w)\)の値- \(Rは\)
    3行目は含ま\を(\ w)の整数\(C1、C2、...、CW(0≤c_j≤h)\) -の値\(C \)

    出力

    回答モジュロ印刷\(十億七(10 ^ 9 + 7)\)

    入力

    3 4 
    0 3 1 
    0 2 3 0
    

    出力

    2
    

    入力

    1 1 
    0 
    1
    

    出力

    0
    

    入力

    16 19 
    16 16 16 16 15 15 0 5 0 4 9 9 1 4 4 0 8 16 12 
    6 12 19 15 8 6 19 19 14 6 9 16 10 11 15 4
    

    出力

    797922655
    

    注意

    最初の例では、これは、他の可能なケースです。

    第2の例では、そのような満足するグリッドを作成することは不可能です\(R \) \(C \)値。
    第三の例では、回答剰余を印刷するようにしてください\((10 ^ 9 + 7)\)

問題の解決策

どのように多くのグリッドに尋ねた質問には、一定の条件を満たすことができます。
入力ので\(r_j \) セクション\(J \)ラインの前に\(r_j + 1 \)グリッドが決定される(フロント\(r_j \)一方が黒であり、\(r_j + 1 \) 1)が白です。
だから我々は単に列挙し、それぞれの位置が同時にある\(r_j + 1 \)\(C_I + \ 1)外。
これらの位置は、白または黒であることができるという点で、これらの位置の数を特定します。
プログラム番号の条件を満たしている(POW(2、SUMを)\)\
時間の複雑さがある\(O(HW)\)です。
ここでは、注意しなければなりません:
行と列に反する条件の数、プログラム数はゼロであるべきとき。
例えば、中\((J、r_j + 1 )\) 上の位置満足\(R&LTの\)要件は白色であるが、しかし、もし\(j≤cr_j +。1 {} \) すなわちを満足\(C \ )の要件はゼロにプログラム番号、その後、黒です。
コードの場合:

#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
int n,m,ans;
int a[1009],b[1009];
long long ksm(int p){
    long long s=2;
    long long ans=1;
    while(p){
        if(p&1) ans*=s;
        ans%=mod;
        s=s*s%mod;
        p/=2;
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int j=1;j<=n;j++)
        scanf("%d",&a[j]);
    for(int j=1;j<=m;j++)
        scanf("%d",&b[j]);
    for(int j=1;j<=n;j++)
        if(j<=b[a[j]+1]){
            printf("0");
            return 0;
        }
    for(int j=1;j<=m;j++)
        if(j<=a[b[j]+1]){
            printf("0");
            return 0;
        }
    for(int j=1;j<=n;j++)
        for(int i=a[j]+2;i<=m;i++)
            if(j>b[i]+1) ans++;
    printf("%lld",ksm(ans));
    return 0;
}

おすすめ

転載: www.cnblogs.com/linjiale/p/11611736.html