NOIP 膜你题 DAY2

NOIp膜你题   Day2

duliu 出题人:ZAY   

 题解

这就是一道组合数问题鸭!!!  可是泥为什么没有推出式子!!

首先我们知道的是 m 盆花都要摆上,然后他们的顺序不定(主人公忘记了)

所以初步得到一个排列数 P( m,m ) , 即 Pmm  

那么我们就还剩下 n-m 个空位置,这些空位置都是不可以放花的,于是我们逆向思维一下:  

  n-m  个位置不放花,也就是可以在这些位置周围插空放花,把这些位置隔开,那么就可以把m盆花放到 n-m+1 个空里,由于这是对于空位置来说的,没有顺序可言,每个都是一毛一样的,所以得到一个组合数  C(n-m+1 , m) , 即 Cn-m+1m  

所以 ans = P( m,m ) * C( n-m+1 , m ) 

               = m! * (n-m+1)! / [ m! * (n-m+1 - m)! ]

                  化简一下就是下面

               =(n-m+1)*(n-m+1-1)*......*(n-2m+2)

注意

ans 要开 long long , 试过毒了,数据不开 long long 会炸

代码

#include<bits/stdc++.h>

using namespace std;

int type,n,m,p;
long long ans=1;

int main()
{
    freopen("ilove.in","r",stdin);
    freopen("ilove.out","w",stdout);
    
    scanf("%d%d%d%d",&type,&n,&m,&p);
    
    if(n==1&&m==1)  { printf("1\n");   return 0; }
    
    int a=n-m+1,b=n-m-m+2;
    for(int i=a;i>=b;i--)
      ans=(ans%p*i%p)%p;
    
    printf("%ld\n",ans);
    return 0;
    
}

题解

代码

 45‘代码   后边超时辣

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>

using namespace std;


string s[100009],s1;
int n,m,q;
int qus,num,l,r;
long long ans=0;


int main()
{
    freopen("lin.in","r",stdin);
    freopen("lin.out","w",stdout);
    scanf("%d%d%d",&n,&m,&q);
    
    if(q==0) return 0;
    
    for(int i=1;i<=m;i++)
      cin>>s[i];
      
    for(int i=1;i<=q;i++)
    {
        ans=0;
        scanf("%d",&qus);
        if(qus==0)
        {
            scanf("%d%d",&l,&r);
            
            int flag=520,cnt=0;
            
            for(int j=0;j<n;j++)
            {
                if(flag==0) break;
                bool glf=0;
                char mp;
                mp=s[l][j];
                if(mp!='?') glf=0;
                else glf=1;
                for(int k=l+1;k<=r;k++)
                {
                    if(s[k][j]!='?')
                    {
                        if(mp=='?')
                        {
                            glf=1;
                            mp=s[k][j];
                            continue;
                        }
                        if(mp!='?'&&mp!=s[k][j]) 
                        {
                            flag=0;
                            continue;
                        }
                        
                    }
                    
                    else if(s[k][j]=='?')
                    {
                        if(glf==0) glf=1;
                    }
                    
                    
                }
                if(mp!='?') glf=0;
                cnt+=glf;
            }
            
            if(flag==0) {printf("0\n");} 
            else
             {
                 ans=pow(2,cnt);
                printf("%ld\n",ans);
             
             }
        }
        if(qus==1)
        {
            scanf("%d",&num);
            cin>>s1;
            s[num]=s1;
        }
    }

    return 0;
}

 thingKing  但是下面这个它还没过样例

#include<bits/stdc++.h>

using namespace std;

int n,m,q;
string s[100010],s1;
int opt,l,r,pos;

inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

int main()
{
//    freopen("lin.in","r",stdin);
//    freopen("lin.out","w",stdout);
    
    n=read(); m=read(); q=read();
    for(int i=1;i<=m;i++)
      cin>>s[i];
     
/*    cout<<"\n";  
    for(int i=1;i<=m;i++)
      cout<<s[i] <<"\n"; 
*/    cout<<"\n";
      
    for(int i=1;i<=q;i++)
    {
        opt=read();
        if(opt==1)
        {
            pos=read();
            cin>>s1;
            s[pos]=s1;        
        }
        else
        {
            l=read();r=read();
            
            long long ans;
            int flag=1,cnt=0;
            
            for(int j=0;j<n;j++)
            {
                if(flag==0) break;
                int flag0=0,flag1=0,flag2=0;
                for(int k=l;k<=r;k++)
                {
                    if(s[k][j]=='0') flag0++;
                    if(s[k][j]=='1') flag1++;
                    if(s[k][j]=='?') flag2++;
                }
                
                if(flag0!=0&&flag1!=0) { flag=0; continue; }    
                else if(flag2==(r-l+2)) cnt++;
                 
            }
            
            if(flag==0) ans=0;
            else ans=pow(2,cnt);
            
//            printf("%d %d ",flag,cnt);
            
            printf("%ld\n",ans);
            
        }
    }
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xiaoyezi-wink/p/11082601.html
今日推荐