对于第一组样例,最终的学号分配方案有以下4种:
[1,2,3], [1,3,2], [2,1,3], [3,1,2][1,2,3],[1,3,2],[2,1,3],[3,1,2]
分配之后每个学生的学号均不相同,且这几种方案的总修改量都是最小的。
对于第二组样例,每个学生的学号已经都不相同,所以无需修改,所以最终分配方案只有11种,即[1,5][1,5]。
思路:
假设一开始1 1 1 2 要变成1 2 2 2(三个2中选2个变2)现在2多了(1的个数-1)个 所以就从3个中选2个变成3 -> 1 2 3 3 在两个3中选1个变4
so 就是概率题 即n个中选(n-1)个即n中选1 所以答案就是3*3*2;
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long ll mod=1e9+7; map<ll,ll>mm; int main() { ll x,n; cin>>n; for (int i = 0; i < n; i++) scanf("%lld", &x),mm[x]++; ll ans=1; map<ll,ll>::iterator it; for(it=mm.begin();it!=mm.end();it++)//要用map 否则用数组什么的 范围10^18 for会超时啊 迭代器遍历 只有mm【x】有值才会遍历到 so 不会超时噢 { ll yy=it->second; ans=ans*yy%mod; if(yy>1)mm[it->first+1]+=(yy-1); } printf("%lld\n", ans); return 0; }