Comet OJ 分配学号 map
Posted ydw--
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Comet OJ 分配学号 map相关的知识,希望对你有一定的参考价值。
题目描述
今天,是JWJU给同学们分配学号的一天!为了让大家尽可能的得到自己想要的学号,鸡尾酒让大家先从[1,10^18] 中随机挑选一个数字作为自己的学号。但是总有一些心有灵犀的小伙伴们选择了一样的数字——显然这样是不合法的,因为每个人的学号都应该是唯一的。
于是鸡尾酒决定调整大家的学号。他采用如下两个原则来修改:
1、只增不减,每个人的最终学号 ≥ 每个人初始选择的学号
2、总修改量尽量少,总修改量指每一个人的改动量之和。(改动量即为最终学号减初始学号的值)
注意,修改后的最终学号可以大于10^18。
很显然,如果现在有两个同学 A 和 B,初始选择的学号均为1号,他们有可能被鸡尾酒改动成 A 同学为 1 号和 B 同学为 2 号,或者改动成 B 同学为 1 号和 A 同学为 2 号。
鸡尾酒邪魅一笑,他想让你告诉他,大家的最终学号共有多少种不同的分配方案。
输入描述
第一行包含一个正整数 n,代表学生的数量(1≤n≤105)
接下来一行包含 n 个正整数,分别代表每个学生的初始选择的学号。(取值范围[1,10^18])
输出描述
输出一个整数表示最终学号的方案数。(答案对 10^9+7 取模)
在两个最终学号的分配方案中,若存在某一个学生在两个方案中的学号不相同,则认为是这两个方案是不同的分配方案。
样例输入 1
3 1 1 2
样例输出 1
4
样例输入 2
2 1 5
样例输出 2
1
提示
对于第一组样例,最终的学号分配方案有以下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;
以上是关于Comet OJ 分配学号 map的主要内容,如果未能解决你的问题,请参考以下文章