链接:https://ac.nowcoder.com/acm/contest/358/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
众所周知,每个人都有自己的rp值(是个非负实数),膜别人可以从别人身上吸取rp值。
然而当你膜别人时,别人也会来膜你,互膜一段时间后,你们就平分了两人原有的rp值,当你膜过一个人之后,你就不能再膜那个人了
出题人发现自己的rp值为x,出题人周围有n个人,第i个人的rp值为a[i]
你要选择膜哪些人和膜人的顺序,使出题人的最终rp值最大
第一行两个数n,x,人数和出题人的初始rp值 第二行n个数,第i个数a[i]表示第i个人的rp值
一行一个数表示出题人的最终rp值(保留三位小数)
示例1
复制
1 0 1
复制
0.500
数据范围: n<=100000,a[i]<=100000,x<=100000,(a[i],x都是整数)
分析:首先可以要膜比原来大的,比原来值小的直接pass,第二,要按照从小到大排序(举两个值一算就ok)
((x+a)/2+b)/2=(x+a)/4+b/2
#include
using namespace std;
typedef long long ll;
const ll N=1e5+5;
int n;
double x,a[N];
int main()
{
scanf("%d%lf",&n,&x);
for(int i=1;i<=n;i++)
scanf("%lf",&a[i]);
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
double tmp=(x+a[i])/2.0;
if(tmp>x)
{
x=tmp;
}
}
printf("%.3lf",x);
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/358/B
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
出题人早上起床就打算穿衣服,他有两箱衣服,因为懒,他在这两天只打算打开一个箱子.
两个箱子中一个有n件衣服,其中有x件女装,另一个有m件衣服,其中有y件女装.
出题人在第一天随机挑一个箱子后,接下来的两天就会从此箱子中随机找一件衣服穿.
又因为出题人懒而且很有钱,所以他穿完衣服后不会去洗,而是直接扔进垃圾桶,也不会放回原来的箱子.
已知出题人第1天穿了女装,求他第二天依然穿女装的概率
第一行包含5个整数n,m,x,y,t
若t=0,则在第一行输出概率(四舍五入保留小数点后3位,概率为0输出0.000,概率为100%输出1.000) 若t=1,则在第一行输出概率(最简分数形式,概率为0输出0/1,概率为100%输出1/1)
示例1
复制
10 10 8 8 1
复制
7/9
2<=n,m<=10000 2<=x<=n且2<=y<=m
贝叶斯公式
官网题解
#include
#include
#include
#include
#define ll long long
using namespace std;
ll a[1000000];
ll gcd(ll a,ll b) { return b == 0 ? a : gcd(b, a % b); }
int main()
{
ll n,m,x,y,t;
cin>>n>>m>>x>>y>>t;
if(t==0)
{
double a=x*(x-1)*m*(m-1)+y*(y-1)*n*(n-1);
double b=(n-1)*(m-1)*(x*m+n*y);
printf("%0.3lf\n",a*1.0/b);
}
else{
ll a=x*(x-1)*m*(m-1)+y*(y-1)*n*(n-1);
ll b=(n-1)*(m-1)*(x*m+n*y);
if(a==0){
cout<<"0/1";
}
else if(a==b){
cout<<"1/1";
}else{
ll k=gcd(a,b);
a/=k;
b/=k;
cout<
链接:https://ac.nowcoder.com/acm/contest/358/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
出题人的妹子送了出题人一个手环,这个手环上有 n 个珠子,每个珠子上有一个数。
有一天,出题人和妹子分手了,想把这个手环从两个珠子间切开,并按顺时针顺序展开成一条链。
可以发现,这条链一共有 n 种可能性。求这 n 种可能性的逆序对数之积模 1000000007。
第一行一个数 n,表示珠子个数。 接下来一行 n 个数,以顺时针顺序给出每个珠子上的整数
一个数,表示答案。
示例1
复制
4 1 3 2 3
复制
24
一共有 4 种方式: 1 3 2 3;3 1 3 2;2 3 1 3;3 2 3 1; 逆序对数分别为 1,3,2,4,积为 24。
n<=200000,-10^9<=珠子上的整数<=10^9。
分析:
离散化+树状数组+规律,具体思路:https://blog.csdn.net/sdz20172133/article/details/86363864
但这题和那一题稍微不同,上一题是0~n-1的全排列,所以,没有重复的数,但是这题可能有,所以这题的那个使用规律时,很难确定比某个数大的数有多少,比某个数小的数有多少,我的思路为:num[i]为i的个数(i是离散化后的对应的位置,注意离散化不去重),比他大的个数:n-num[i]-i+1,比他小的数就为i个。
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int mod=1000000007;
const int MAXN=200000+5;//最大元素个数
int n;//元素个数
ll c[MAXN],a[MAXN];//c[i]==A[i]+A[i-1]+...+A[i-lowbit(i)+1]
ll b[MAXN];
//返回i的二进制最右边1的值
int lowbit(int i)
{
return i&(-i);
}
//返回A[1]+...A[i]的和
ll sum(int x){
ll sum = 0;
while(x){
sum += c[x];
x -= lowbit(x);
}
return sum;
}
//令A[i] += val
void add(int x, ll val){
while(x <= n){
c[x] += val;
x += lowbit(x);
}
}
int num[MAXN];
int main()
{
while(scanf("%d",&n)!=-1)
{
memset(c,0,sizeof(c));
memset(num,0,sizeof(num));
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
ll ans=0;
int sum1=1;
for(int i=n;i>0;i--)
{
int pos=lower_bound(b+1,b+n+1,a[i])-b;
num[pos]++;
ans=(ans+sum(pos-1))%mod;
add(pos,1);
}
ll sum=ans;
//cout<