链接:https://ac.nowcoder.com/acm/contest/358/A
来源:牛客网
众所周知,每个人都有自己的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都是整数)
思路:排个序然后从小到大地和自己大的数取平均数
#include<bits/stdc++.h>
#define MOD 1000000007
#define INF 0x3f3f3f3f
using namespace std;
#define ll long long int
const ll MAXN=1e5+5;
int n;
double x;
double a[MAXN];
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 t=(x+a[i])/2.0;
if(t>x)
{
x=t;
}
}
cout<<fixed<<setprecision(3)<<x<<endl;
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/358/B
来源:牛客网
题目描述
出题人早上起床就打算穿衣服,他有两箱衣服,因为懒,他在这两天只打算打开一个箱子.
两个箱子中一个有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
思路:贝叶斯定理
已经知道第一天穿女装了,那么选取两个箱子的概率就不是1:1
ans=p(两次都取到女装)/p(第一次取到女装)
p(两次都取到女装)=(1/2)*[(x*(x-1))/(n*(n-1)) + (y*(y-1))/(m*(m-1)) ]
p(第一次取到女装)=(1/2)*[x/n + y/m]
long long 暴力求分子和分母化简就好
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5;
ll t,n,m,x,y;
ll gcd(ll a,ll b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
scanf("%lld%lld%lld%lld%lld",&n,&m,&x,&y,&t);
ll xx=x*(x-1)*m*(m-1)+y*(y-1)*n*(n-1);
ll yy=(n-1)*(m-1)*(x*m+n*y);
ll gc=gcd(xx,yy);
xx=xx/gc;
yy=yy/gc;
if(t==1)
cout<<xx<<"/"<<yy<<endl;
else{
double ans=1.0*xx/yy+0.0005;
cout<<fixed<<setprecision(3)<<ans<<endl;
}
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/358/D
来源:牛客网
题目描述
出题人的妹子送了出题人一个手环,这个手环上有 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。
树状数组离散化再去求逆序对数
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 200005
#define mod 1000000007
struct AA
{
int rt,x,t;
bool operator<(const AA&aa)const
{
if(x==aa.x) return rt<aa.rt;
return x<aa.x;
}
}ppos[200005];
bool cmp(AA aa,AA bb)
{
return aa.rt<bb.rt;
}
ll a[500005],summ[500005];
ll ans,answ;
int lowbit(int i)
{
return i&(-i);
}
void add(int i)
{
while(i<=MAXN)
{
a[i]++;
i+=lowbit(i);
}
return;
}
ll sum(int i)
{
ll s=0;
while(i>0)
{
s+=a[i];
i-=lowbit(i);
}
return s;
}
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&ppos[i].x);
ppos[i].rt=i;
}
sort(ppos+1,ppos+1+n);
ppos[1].t=1;
summ[1]=1;
for(int i=2;i<=n;i++)
{
if(ppos[i].x==ppos[i-1].x)
ppos[i].t=ppos[i-1].t;
else
ppos[i].t=ppos[i-1].t+1;
summ[ppos[i].t]=i;
}
sort(ppos+1,ppos+1+n,cmp);
for(int i=1;i<=n;i++)
{
add(ppos[i].t);
ans+=i-sum(ppos[i].t);
ans%=mod;
}
answ=ans%mod;
for(int i=1;i<n;i++)
{
ans+=(n-summ[ppos[i].t])-summ[ppos[i].t-1];
ans=(ans+mod)%mod;
answ*=ans;
answ%=mod;
}
printf("%lld\n",answ);
return 0;
}