Codeforces Round #341 (Div. 2)总结

A题:

A题题目链接

题目描述:

A. Wet Shark and Odd and Even
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Today, Wet Shark is given n integers. Using any of these integers no more than once, Wet Shark wants to get maximum possible even (divisible by 2) sum. Please, calculate this value for Wet Shark.

Note, that if Wet Shark uses no integers from the n integers, the sum is an even integer 0.

Input

The first line of the input contains one integer, n (1 ≤ n ≤ 100 000). The next line contains n space separated integers given to Wet Shark. Each of these integers is in range from 1 to 109, inclusive.

Output

Print the maximum possible even sum that can be obtained if we use some of the given integers.

Sample test(s)
input
3
1 2 3
output
6
input
5
999999999 999999999 999999999 999999999 999999999
output
3999999996
Note

In the first sample, we can simply take all three integers for a total sum of 6.

In the second sample Wet Shark should take any four out of five integers 999 999 999.

题意:

给定n个整数,每个整数的范围是从1-10^9,在这n个数中,相加得到最大的偶数并输出,每个数最多使用一次,若找不到这样的最大的偶数,则输出0.

解析:

将这n个整数中的奇数另外存储,偶数全部相加,然后将这些奇数升序排序,若奇数为偶数个,则最后输出的结果为这n个整数之和,若奇数为奇数个,则不加最小的那个奇数,这样的话得到最大的偶数(偶数个奇数相加得偶数,奇数个奇数相加得奇数)

完整代码实现:

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5;
ll sum[maxn+10],odd[maxn+10];
int main()
{
    ll n;
    while(scanf("%I64d",&n) == 1 && n)
    {
        ll ans = 0,j = 0;
        for(ll i = 0;i < n;i++)
        {
            scanf("%I64d",&sum[i]);
            if(sum[i] % 2 == 0)
                ans += sum[i];
            else
            {
                odd[j] = sum[i];
                j++;
            }
        }
        if(j % 2 == 0)   //偶数个奇数
        {
            for(ll i = 0;i < j;i++)
                ans += odd[i];
        }
        else         //奇数个奇数
        {
            sort(odd,odd + j);
            for(int i = 1;i < j;i++)
                ans += odd[i];
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

B题:

B题题目链接

题目描述:

B. Wet Shark and Bishops
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Today, Wet Shark is given n bishops on a 1000 by 1000 grid. Both rows and columns of the grid are numbered from 1 to 1000. Rows are numbered from top to bottom, while columns are numbered from left to right.

Wet Shark thinks that two bishops attack each other if they share the same diagonal. Note, that this is the only criteria, so two bishops may attack each other (according to Wet Shark) even if there is another bishop located between them. Now Wet Shark wants to count the number of pairs of bishops that attack each other.

Input

The first line of the input contains n (1 ≤ n ≤ 200 000) — the number of bishops.

Each of next n lines contains two space separated integers xi and yi (1 ≤ xi, yi ≤ 1000) — the number of row and the number of column where i-th bishop is positioned. It's guaranteed that no two bishops share the same position.

Output

Output one integer — the number of pairs of bishops which attack each other.

Sample test(s)
input
5
1 1
1 5
3 3
5 1
5 5
output
6
input
3
1 1
2 3
3 5
output
0
Note

In the first sample following pairs of bishops attack each other: (1, 3)(1, 5)(2, 3)(2, 4)(3, 4) and (3, 5). Pairs (1, 2)(1, 4)(2, 5)and (4, 5) do not attack each other because they do not share the same diagonal.


题意:

给定一个整数n,然后再给定n个坐标值,坐标值的取值范围为[1,1000],每个坐标值上都有一个“象”棋子,如果有两个“象”棋子在棋盘同一对角线上的话,那么这两个“象“棋子则可以相互攻击,并且无视对角线上的其它棋子(即只要在同一对角线上则可互相攻击),问在这给定的n个坐标值上的”象“棋子,总共有多少组可以互相攻击的”象“棋子?

解析:


利用棋盘对角线的特殊性,由于棋盘为正方形棋盘,那么主对角线和与之对称的斜对角线上的点所在直线的斜率分别为k1 = 1和k2 = -1

那么在主对角线任取两点(x1,y1),(x2,y2),则有

y2 -  y1 = x2 - x1;

移项得

y2 - x2 = y1 - x1;

同理,在斜对角线存在如下规律:

y2 + x2 = y1 + x1;

因此我们得出结论:

在同一主对角线上的点: 横纵坐标之差相等。

在同一斜对角线上的点: 横纵坐标之和相等。

而坐标值范围为[1,1000].我们则可以利用"桶"的思想,来计算在同一对角线上点的个数,但是需要注意的问题是,横纵坐标之差可能为负值,并且相差不超过1000,因此我们可以将其存储至flag+1000,这样的话避免了数组下标为负值的情况。

然后就是计算在这给定的n个坐标值上的”象“棋子,总共有多少组可以互相攻击的”象“棋子?

因为在同一对角线上的“象”棋子均可以两两攻击,那么这就是一个组合问题了,只需求得在同一对角线上的点有多少(i)个,然后结果再加上C(i,2)即可。(i>=2的情况下)

完整代码实现:

#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
int flag1[4000],flag2[4000];   //用来存储主对角线和反主对角线的同对角线的个数
int main()
{
    int n,x,y;
    while(scanf("%d",&n) == 1)
    {
        memset(flag1,0,sizeof(flag1));
        memset(flag2,0,sizeof(flag2));
        ll ans = 0;
        for(int i = 0;i < n;i++)
        {
            scanf("%d %d",&x,&y);
            flag1[x+y]++;
            flag2[x-y+1000]++;   //防止数组越界
        }
        for(int i = 0;i < 3000;i++)
        {
            if(flag1[i] > 1)
                ans += (flag1[i] * (flag1[i] - 1)) / 2;
            if(flag2[i] > 1)
                ans += (flag2[i] * (flag2[i] - 1)) / 2;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
C题:

C题题目链接

题目描述:

C. Wet Shark and Flowers
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

There are n sharks who grow flowers for Wet Shark. They are all sitting around the table, such that sharks i and i + 1 are neighbours for all i from 1 to n - 1. Sharks n and 1 are neighbours too.

Each shark will grow some number of flowers si. For i-th shark value si is random integer equiprobably chosen in range from li to ri. Wet Shark has it's favourite prime number p, and he really likes it! If for any pair of neighbouring sharks i and j the product si·sj is divisible by p, then Wet Shark becomes happy and gives 1000 dollars to each of these sharks.

At the end of the day sharks sum all the money Wet Shark granted to them. Find the expectation of this value.

Input

The first line of the input contains two space-separated integers n and p (3 ≤ n ≤ 100 000, 2 ≤ p ≤ 109) — the number of sharks and Wet Shark's favourite prime number. It is guaranteed that p is prime.

The i-th of the following n lines contains information about i-th shark — two space-separated integers li and ri (1 ≤ li ≤ ri ≤ 109), the range of flowers shark i can produce. Remember that si is chosen equiprobably among all integers from li to ri, inclusive.

Output

Print a single real number — the expected number of dollars that the sharks receive in total. You answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

Sample test(s)
input
3 2
1 2
420 421
420420 420421
output
4500.0
input
3 5
1 4
2 3
11 14
output
0.0
Note

A prime number is a positive integer number that is divisible only by 1 and itself. 1 is not considered to be prime.

Consider the first sample. First shark grows some number of flowers from 1 to 2, second sharks grows from 420 to 421 flowers and third from 420420 to 420421. There are eight cases for the quantities of flowers (s0, s1, s2) each shark grows:

  1. (1, 420, 420420): note that s0·s1 = 420s1·s2 = 176576400, and s2·s0 = 420420. For each pair, 1000 dollars will be awarded to each shark. Therefore, each shark will be awarded 2000 dollars, for a total of 6000 dollars.
  2. (1, 420, 420421): now, the product s2·s0 is not divisible by 2. Therefore, sharks s0 and s2 will receive 1000 dollars, while shark s1will receive 2000. The total is 4000.
  3. (1, 421, 420420): total is 4000
  4. (1, 421, 420421): total is 0.
  5. (2, 420, 420420): total is 6000.
  6. (2, 420, 420421): total is 6000.
  7. (2, 421, 420420): total is 6000.
  8. (2, 421, 420421): total is 4000.

The expected value is .

In the second sample, no combination of quantities will garner the sharks any money.


题意:

给定n值  和一个素数p  然后给定n个区间,每个区间可以等概率的取出一个数字  然后相当于是组成一个数组  然后当i个和i+1的数的积能够整除素数p的时候  能够获得两千块

其中第一个数和最后一个数也是相邻的,相当于形成一个环形数组。问能够获得的金额数目的数学期望

数学期望的定义描述:

数学期望
E(X) = X1*p(X1) + X2*p(X2) + …… + Xn*p(Xn)
X1,X2,X3,……,Xn为这几个数据,p(X1),p(X2),p(X3),……p(Xn)为这几个数据的概率函数。
解析:

这道题看似长篇大论,而且由于题目是英文并且冗长,但是读懂题意后,其实并不难。题目要求输出的是能够获得金额的数学期望,那么我们可以从这里入手。既然当相邻的两个数的积能够整除素数p时,那么每次获得的钱都是2000的倍数(两个数都有),而要两个数的积能够整除素数p,那么至少有一个数含有质因子p,这样的话才能整除素数p,而这两个数都是从相邻区间中取出的数字,则为了方便我们可以计算积不能整除p的概率。那么假设在区间1取得不能够整除p的数的概率为p1,在区间2取得不能够整除p的数的概率为p2,则在两个区间同时不能取得整除p的数的概率为p1*p2,而这样我们能算得在两个区间能取得至少有一个整除p的数的概率为1 - p1*p2,这样的话我们根据数学期望公式则可算得能够获得金额的数学期望。

需要注意的问题是,如果区间为[6,7],给定素数为3,那么其实在给定区间是有一个数能够整数素数p的,所以应该考虑这种特殊情况。

完整代码实现:

#include<cstdio>
#include<algorithm>
const int maxn = 1e5;
using namespace std;
double p[maxn+10];
int main()
{
    int n,q;
    while(scanf("%d %d",&n,&q) == 2)
    {
        int l,r;
        for(int i = 0;i < n;i++)
        {
            scanf("%d %d",&l,&r);
            int temp = r / q - l / q;
            if(l%q==0)
                temp++;
            p[i] = 1.0 - (double)temp/(r-l+1);
        }
        double ans = 0;
        for(int i = 0;i < n-1;i++)
        {
            ans +=(1-p[i]*p[i+1])*2000;
        }
        ans += (1-p[0]*p[n-1])*2000;   //第一个数和最后一个数单独处理
        printf("%.10f\n",ans);
    }
    return 0;
}
D题:

D题题目链接

题目描述:

D. Rat Kwesh and Cheese
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Wet Shark asked Rat Kwesh to generate three positive real numbers xy and z, from 0.1 to 200.0, inclusive. Wet Krash wants to impress Wet Shark, so all generated numbers will have exactly one digit after the decimal point.

Wet Shark knows Rat Kwesh will want a lot of cheese. So he will give the Rat an opportunity to earn a lot of cheese. He will hand the three numbers xy and z to Rat Kwesh, and Rat Kwesh will pick one of the these twelve options:

  1. a1 = xyz;
  2. a2 = xzy;
  3. a3 = (xy)z;
  4. a4 = (xz)y;
  5. a5 = yxz;
  6. a6 = yzx;
  7. a7 = (yx)z;
  8. a8 = (yz)x;
  9. a9 = zxy;
  10. a10 = zyx;
  11. a11 = (zx)y;
  12. a12 = (zy)x.

Let m be the maximum of all the ai, and c be the smallest index (from 1 to 12) such that ac = m. Rat's goal is to find that c, and he asks you to help him. Rat Kwesh wants to see how much cheese he gets, so he you will have to print the expression corresponding to that ac.

Input

The only line of the input contains three space-separated real numbers xy and z (0.1 ≤ x, y, z ≤ 200.0). Each of xy and z is given with exactly one digit after the decimal point.

Output

Find the maximum value of expression among xyzxzy(xy)z(xz)yyxzyzx(yx)z(yz)xzxyzyx(zx)y(zy)x and print the corresponding expression. If there are many maximums, print the one that comes first in the list.

xyz should be outputted as x^y^z (without brackets), and (xy)z should be outputted as (x^y)^z (quotes for clarity).

Sample test(s)
input
1.1 3.4 2.5
output
z^y^x
input
2.0 2.0 2.0
output
x^y^z
input
1.9 1.8 1.7
output
(x^y)^z
题意:

题目意思其实很简单,就是给定浮点数x,y,z的值,求上面一系列表达式中的最大值,并输出该表达式。

解析:

由于200^200^200过大,这时候我们联想到高中学到的知识,毕竟两个带有乘方的数的大小,可以将这两个数作为真数,再以10或者自然对数为底,对这两个数取对数

所以这题我们将所有的数以10为底取对数,发现取一次对数后,前缀仍然有200^200,依旧过大,所以我们可以取两次对数。

但是这里有一个需要注意的问题,对数的真数必须大于0,而对第一个表达式取两次对数,得到的表达式为:

z*log10(y) + log10(log10(x)),由于真数必须大于0,所以log10(x) > 0 ,即得x > 1,所以我们分两种情况考虑

一种是x,y,z均小于1,另一种是x,y,z中至少有一个数大于1

完整代码:

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const char *a[] =
{
    "x^y^z",
    "x^z^y",
    "(x^y)^z",
    "(x^z)^y",
    "y^x^z",
    "y^z^x",
    "(y^x)^z",
    "(y^z)^x",
    "z^x^y",
    "z^y^x",
    "(z^x)^y",
    "(z^y)^x"
};
const double minn = -1e18;
const double esp = 1e-6;
int main()
{
    double x,y,z;
    while(scanf("%lf %lf %lf",&x,&y,&z) == 3)
    {
        int flag = 0;
        double p[12];
        if(x > 1 || y > 1 || z > 1)
        {
            p[0] = x > 1 ? z*log10(y) + log10(log10(x)) : minn;
            p[1] = x > 1 ? y*log10(z) + log10(log10(x)) : minn;
            p[2] = x > 1 ? log10(z) + log10(y*log10(x)) : minn;
            p[3] = x > 1 ? log10(y) + log10(z*log10(x)) : minn;
            p[4] = y > 1 ? z*log10(x) + log10(log10(y)) : minn;
            p[5] = y > 1 ? x*log10(z) + log10(log10(y)) : minn;
            p[6] = y > 1 ? log10(z) + log10(x*log10(y)) : minn;
            p[7] = y > 1 ? log10(x) + log10(z*log10(y)) : minn;
            p[8] = z > 1 ? y*log10(x) + log10(log10(z))  : minn;
            p[9] = z > 1 ? x*log10(y) + log10(log10(z))  : minn;
            p[10] = z > 1 ? log10(y) + log10(x*log10(z)) : minn;
            p[11] = z > 1 ? log10(x) + log10(y*log10(z)) : minn;
        }
        else
        {
            p[0] = (double)pow(x,pow(y,z));
            p[1] = (double)pow(x,pow(z,y));
            p[2] = (double)pow(pow(x,y),z);
            p[3] = (double)pow(pow(x,z),y);
            p[4] = (double)pow(y,pow(x,z));
            p[5] = (double)pow(y,pow(z,x));
            p[6] = (double)pow(pow(y,x),z);
            p[7] = (double)pow(pow(y,z),x);
            p[8] = (double)pow(z,pow(x,y));
            p[9] = (double)pow(z,pow(y,x));
            p[10] = (double)pow(pow(z,x),y);
            p[11] = (double)pow(pow(z,y),x);
        }
        double max_num = p[0];
        for(int i = 0; i < 12; i++)
        {
            if(p[i] > max_num && p[i] - max_num > esp)
            {
                max_num = p[i];
                flag = i;    //记录取得最大值的组合
            }
        }
        printf("%s\n",a[flag]);
    }
    return 0;
}

如有错误,还请指正,O(∩_∩)O谢谢



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值