absi2011
一个新的开始吧w 希望这一次能如我所愿w

1004

我们考虑一下,首先奇数的不可能有效

首先,如果是奇*奇,显然怎么构造都行

如果奇*偶,那么只有偶数的有效,奇数不可能有效

那么偶数就()()()这样就好了

所以我们考虑偶数*偶数的

我们分两种情况:

1,我们第一行,第一列,最后一行最后一列都不要了

这情况下

我们可以构造一个这样的

((((((((

()()()()

(()()())

.........

))))))))

也就是说,第一行第一列放(

最后一行一列)

交界处无所谓

然后剩下的()交替,肯定数量相等而且两两抵消

方案数n+m-4

---------------------------------

还有一个情况是这样

((((((

)()()(

()()()

))))))

这样的话,我们发现

6列全部满足,此外我们造了一行满足的

我们发现,第一行一定是(,最后一行一定是),其余的我们可以满足一半的行数

用这种办法构造,我们得到的答案是n+(m-2)/2的

两者取max即可

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    int zu;
    for (zu=0;zu<t;zu++)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        if ((n%2==0)&&(n>=8)&&(m%2==0)&&(m>=8))
        {
            int i,j;
            for (j=0;j<m;j++)
            {
                printf("(");
            }
            printf("\n");
            for (i=1;i<n-1;i++)
            {
                printf("(");
                int j;
                for (j=1;j<m-1;j++)
                {
                    if ((i+j)%2==0)
                    {
                        printf("(");
                    }
                    else
                    {
                        printf(")");
                    }
                }
                printf(")");
                printf("\n");
            }
            for (j=0;j<m;j++)
            {
                printf(")");
            }
            printf("\n");
            continue;
        }
        int val_n=n,val_m=m;
        if (n%2==1) val_m=-1;
        if (m%2==1) val_n=-1;
        int j;
        if (val_n>val_m)
        {
            int i;
            for (i=0;i<n;i++)
            {
                for (j=0;j<m;j++)
                {
                    if (j==0)
                    {
                        printf("(");
                    }
                    else if (j==m-1)
                    {
                        printf(")");
                    }
                    else if ((i%2==0)&&(j%2==1))
                    {
                        printf(")");
                    }
                    else if ((i%2==1)&&(j%2==0))
                    {
                        printf(")");
                    }
                    else
                    {
                        printf("(");
                    }
                }
                printf("\n");
            }
        }
        else
        {
            int i;
            for (i=0;i<n;i++)
            {
                for (j=0;j<m;j++)
                {
                    if (i==0)
                    {
                        printf("(");
                    }
                    else if (i==n-1)
                    {
                        printf(")");
                    }
                    else if ((j%2==0)&&(i%2==1))
                    {
                        printf(")");
                    }
                    else if ((j%2==1)&&(i%2==0))
                    {
                        printf(")");
                    }
                    else
                    {
                        printf("(");
                    }
                }
                printf("\n");
            }
        }
    }
    return 0;
}

============================================

1011

我们直接暴力枚举哪些行要扎掉一个气球,然后开dp....

复杂度有点高,不过反正过了对不对

要写个高精度差评........

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
char c[15][25];
long long dp[25][1<<12];
long long ans[25];
struct bigint
{
    int a[65];
    bigint ()
    {
        memset(a,0,sizeof(a));
    }
    bigint (long long x)
    {
        memset(a,0,sizeof(a));
        int i;
        for (i=0;x!=0;i++)
        {
            a[i]=x%10;
            x/=10;
        }
    }
    int & operator [] (const int x)
    {
        return a[x];
    }
    int operator [] (const int x) const
    {
        return a[x];
    }
    friend bigint operator * (const bigint &a,const bigint &b)
    {
        bigint c;
        int i,j;
        for (i=0;i<30;i++)
        {
            for (j=0;j<30;j++)
            {
                c[i+j]+=a[i]*b[j];
            }
        }
        for (i=0;i<60;i++)
        {
            c[i+1]+=c[i]/10;
            c[i]%=10;
        }
        return c;
    }
    void output()
    {
        int i;
        for (i=60;i>0;i--)
        {
            if (a[i]!=0) break;
        }
        for (;i>=0;i--)
        {
            printf("%d",a[i]);
        }
        printf("\n");
    }
};
int down_val[1<<12];
int cnts[1<<12];
bool must_update[25];
bool empty[25];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int t;
    scanf("%d",&t);
    int zu;
    int i,j;
    for (i=0;i<12;i++)
    {
        down_val[(1<<i)]=i;
    }
    for (i=0;i<(1<<12);i++)
    {
        int j;
        for (j=0;j<12;j++)
        {
            if ((1<<j)&i) cnts[i]++;
        }
    }
    for (zu=0;zu<t;zu++)
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for (i=1;i<=k;i++)
        {
            ans[i]=0;
        }
        for (i=0;i<n;i++)
        {
            scanf("%s",c[i]);
        }
        for (i=0;i<(1<<n);i++)
        {
            int sum=0;
            bool impo=false;
            for (j=0;j<m;j++)
            {
                must_update[j]=false;
                int k;
                empty[j]=true;
                for (k=0;k<n;k++)
                {
                    if ((1<<k)&i)
                    {
                        if (c[k][j]=='Q')
                        {
                            empty[j]=false;
                        }
                        continue;
                    }
                    if (c[k][j]=='Q')
                    {
                        must_update[j]=true;
                    }
                }
                if (must_update[j])
                {
                    sum++;
                    if (empty[j])
                    {
                        impo=true;
                    }
                }
            }
            if (impo) continue;
            if (sum>cnts[i]) continue;
            for (j=0;j<=m;j++)
            {
                int k;
                for (k=i;;k=(k-1)&i)
                {
                    dp[j][k]=0;
                    if (k==0) break;
                }
            }
            dp[0][i]=1;
            for (j=0;j<m;j++)
            {
                if (!must_update[j])
                {
                    int k;
                    for (k=i;;k=(k-1)&i)
                    {
                        dp[j+1][k]+=dp[j][k];
                        if (k==0) break;
                    }
                }
                if (empty[j])
                {
                    continue;
                }
                int k;
                for (k=i;;k=(k-1)&i)
                {
                    int l=k;
                    for (;l!=0;)
                    {
                        int p=l&(-l);
                        l^=p;
                        if (c[down_val[p]][j]=='Q')
                        {
                            dp[j+1][k^p]+=dp[j][k];
                        }
                    }
                    if (k==0) break;
                }
            }
            ans[cnts[i]]+=dp[m][0];
        }
        long long val=1;
        for (i=1;i<=k;i++)
        {
            val*=i;
            (bigint(ans[i])*bigint(val)).output();
        }
    }
    return 0;
}

  

posted on 2018-08-28 21:08  absi2011  阅读(146)  评论(0编辑  收藏  举报