A. Game
题目大意:A有N1个球,B有N2个球,A每次可以扔1-K1个球,B每次可以扔1-K2个球,谁先不能操作谁熟
思路:.....显然每次扔一个球最优....
#include<iostream>
#include<cstdio>
#include <math.h>
#include<algorithm>
#include<string.h>
#include<queue>
#define MOD 10000007
#define maxn 200000
#define LL long long
using namespace std;
int main()
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a<=b)printf("Second\n");else printf("First\n");
return ;
}
B. Permutations
题目大意:给你一个1-n的排列p,要你求在f(p)最大的前提下,字典序为m的排列
思路:一开始想烦了...对于1-n-1的排列,新的数n一定是插入n-1的左边或者右边,这样的排列才是满足f(p)最大的,于是写出来就会发现从小到大每一个数字要么放在当前序列的最前面,要么放在当前序列的最后面,然后就没有然后了
#include<iostream>
#include<cstdio>
#include <math.h>
#include<algorithm>
#include<string.h>
#include<queue>
#define MOD 10000007
#define maxn 200000
#define LL long long
using namespace std;
long long bin[];
int visit[maxn],ans[maxn];
int main()
{
bin[]=;
for(int i=;i<=;i++)bin[i]=bin[i-]*2LL;
int n,anss;
long long m;
while(scanf("%d%I64d",&n,&m)!=EOF)
{
int last=n;
for(int i=,j=;i<=n;i++)
{
int u=bin[n-i-];
if(m<=u)ans[j]=i,j++;
else ans[last]=i,last--,m-=u;
}
for(int i=;i<=n;i++)printf("%d ",ans[i]);
}
return ;
}
G1:Inversions problem
题目大意:对于每个1-n的排列,可以进行K次操作,每次操作可以对随机的一段子序列逆向,问K次操作后逆序数的期望是多少?
思路:敲了发暴力过了G1
#include<iostream>
#include<cstdio>
#include <math.h>
#include<algorithm>
#include<string.h>
#include<queue>
#define MOD 10000007
#define maxn 200000
#define LL long long
using namespace std;
int a[],m,n,up=,down=;
void dfs(int kk,int b[])
{
int c[],d[];
memcpy(d,b,sizeof(d));
if(kk==m+)
{
int inv=;
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
if(b[j]<b[i])inv++;
}
}
up+=inv;down++;
return;
}
for(int i=;i<=n;i++)
for(int j=i;j<=n;j++)
{
for(int k=;k<=j-i+;k++)
{
c[k]=b[j-k+];
}
for(int k=;k<=j-i+;k++)
{
b[i+k-]=c[k];
}
dfs(kk+,b);
for(int k=;k<=j-i+;k++)
{
c[k]=b[j-k+];
}
for(int k=;k<=j-i+;k++)
{
b[i+k-]=c[k];
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
dfs(,a);
printf("%.9lf",1.0*up/down);
return ;
}