2020 年百度之星·程序设计大赛 - 初赛三
解题思路:题目已经说的很明白了,把计算得公式都写出来了,所以直接套公式,把每种优惠得比例算出来,然后取最大即可。
AC代码:
#include<cstdio> #include<iostream> using namespace std; #define maxn 105 int main(void) { int t,n; double b,c; scanf("%d",&t); while(t--) { double sum=0; scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%lf%lf",&b,&c); sum=max(sum,(1.0-c)/(b-c+1.0));//计算并取最大优惠的情况 } printf("%.5lf\n",sum); } return 0; }
解题思路:因为x是(0,1]的,p是(0,2]的,又由于当p>1的时候Alice肯定是拿的大的部分不用换,
否则Alice可能拿的大的可能拿的小的,算出来的期望值为1.25x>x,所以肯定换。
AC代码:
#include<cstdio> #include<iostream> using namespace std; #define maxn 105 int main(void) { int t; double p; scanf("%d",&t); while(t--) { scanf("%lf",&p); if(p<=1) puts("Yes"); else puts("No"); } return 0; }
解题思路:这道题我们要让逆序对最多,一定是按照第一个和最后一个交换,第二个和倒数第二个交换。。。。
很显然我们发现这样的交换只能做n/2次(向下取整)。然后我我们可以观察每次交换能得到的逆序对数。
好了,我们已经发现了4的规律,我们猜测是不是5也是呢?
聪明的你一定发现了什么,我们可以看到n为偶数和n为奇数的情况是不相同的,n为偶数的时候结尾只有1,而n为奇数的时候结尾是3,
而逆序对数,最多就为(n-1)*n/2对,我们可以让sum先等于最多的对数,然后根据m的数减去相应的数就行,我们可以发现其实n为奇数和n为偶数
是两个不同的序列,但是公差都为4,n为奇数的首项为3,n为偶数的首项为1,然后。。。。。,然后就AC了鸭!(可惜比赛的时候写错了,然后wa了好几发)
AC代码:
#include<cstdio> #include<iostream> #define ll long long using namespace std; int main(void) { ll t; ll n,m; ll sum,k; scanf("%lld",&t); while(t--) { scanf("%lld%lld",&n,&m); sum=(n-1)*n/2; if(m<n/2) { k=(n/2-m); if(n&1) sum-=(2*k+1)*k;//前k项和 else sum-=(2*k-1)*k;//前k项和 } printf("%lld\n",sum ); } return 0; }