P1866 编号

摘要:太郎有N只兔子,现在为了方便识别它们,太郎要给他们编号。兔子们向太郎表达了它们对号码的喜好,每个兔子i想要一个整数,介于1和Maxnumber[i]之间(包括1和Maxnumber[i])。当然,每个兔子的编号是不同的。现在太郎想知道一共有多少种编号的方法。你只用输出答案mod 1000000007即可。如果这是不可能的,就输出0。

其实看到这个题,我第一时间想到的是深搜,不过有这句“输出答案mod 1000000007即可”就基本确定不是深搜了。

于是我就换个思路想了想:

第一次我们选择第一个序列的某一个,第二次选择就减少了一次选择机会,只能选择除了选过的以外的了,第三次选择又少了一次,第四次又少了一次......

那么不难想到:第一个*第二个-1*第三个-2*第四个-3......

这样我们稍微画画图就可以得出公式:ans*=(m[i]-sum);

sum是每次应该减少的次数(每次++),m[i]是目前的这个序列一共有多少个数。

代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
unsigned long long n,m[10010],ans=1,sum=0;
int main(){
    scanf("%u",&n);
    for(int i=0;i<n;i++){
        scanf("%u",&m[i]);
    }
    for(int i=0;i<n;i++){//遍历一遍
        ans*=(m[i]-sum)%1000000007;//公式
        sum++;//减少的次数
    }
    printf("%u\n",ans);
    return 0;
}

但是这样我们会发现,当碰到5 1 2 3 2 1这样的数的时候就会over(因为2<那时候的sum,就会得到一个负数)。

那要不我们加个特判:if(m [i]>=sum)的时候才让他执行上面的那个语句?

#include<iostream>
#include<cstdio>
using namespace std;
unsigned long long n,m[1010],ans=1,sum=0;
int main(){
    scanf("%u",&n);
    for(int i=0;i<n;i++){
        scanf("%u",&m[i]);
    }
    for(int i=0;i<n;i++){//遍历
        if(m[i]>=sum){//特判,如果m[i]>=sum才能执行下面的语句。
            ans*=(m[i]-sum);
        }
        else{//否则就直接让ans=0
            ans=0;
            break;
        }
        ans%=1000000007;
        sum++;//减少的次数
    }
    printf("%u\n",ans);
    return 0;
}

可是碰到5 4 5 6 2 1就又难办了(因为这样虽然会得到负数,但是还是会有很多种选编号方法的)。

那该怎么办??

我们的救星来了!他就是——sort,只要用sort排一边序就好了。

如果不排序,我们就不知道前一个选择的号码是不是在现在这个m[i]里面,就会发生前面的情况。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
unsigned long long n,m[1010],ans=1,sum=0;//开大点总没坏处
int main(){
    scanf("%u",&n);
    for(int i=0;i<n;i++){
        scanf("%u",&m[i]);
    }
    sort(m,m+n);//排序一遍,如果不排序,我们就不知道前一个选择的号码是不是在现在这个m[i]里面,就会发生前面的情况。
    for(int i=0;i<n;i++){
        ans*=(m[i]-sum);
        ans%=1000000007;//千万不要忘了这个,如果数大了,不加这个就会over
        sum++;
    }
    printf("%u\n",ans);
    return 0;
}

以上就是我这道题的全部思路,如果有什么不对的地方,还请各位大佬及时向我纠正。

posted @ 2020-05-08 10:51  dgdger  阅读(177)  评论(0编辑  收藏  举报