2021灵动冬令营Day3

本文探讨了多项算法竞赛题目,包括A至G题的解题思路和AC代码。A题通过暴力枚举找到满足条件的直线;B题求解图形面积比例;C题寻找所有数除以同一数余数相同的最小公倍数;D题应用扩展欧几里得算法求解整数分解;E题将循环小数转化为分数;F题计算概率;G题求多项式导数。文章旨在帮助读者提升算法解决实际问题的能力。
摘要由CSDN通过智能技术生成

A - Birthday Cake

Description

Lucy and Lily are twins. Today is their birthday. Mother buys a birthday cake for them. Now we put the cake onto a Descartes coordinate. Its center is at (0, 0), and the cake’s length of radius is 100. There are 2N (N is a integer, 1 ≤ N ≤ 50) cherries on the cake. Mother wants to cut the cake into two halves with a knife (of course a beeline). The twins would like to be treated fairly, that means, the shape of the two halves must be the same (that means the beeline must go through the center of the cake) , and each half must have N cherrie(s). Can you help her? Note: the coordinate of a cherry (x, y) are two integers. You must give the line as form two integers A, B (stands for Ax + By = 0) each number mustn’t in [−500, 500]. Cherries are not allowed lying on the beeline. For each dataset there is at least one solution.

Input

The input file contains several scenarios. Each of them consists of 2 parts: The first part consists of a line with a number N, the second part consists of 2N lines, each line has two number, meaning (x, y). There is only one space between two border numbers. The input file is ended with N = 0.

Output

For each scenario, print a line containing two numbers A and B. There should be a space between them. If there are many solutions, you can only print one of them.

Sample Input
2
-20 20
-30 20
-10 -50
10 -5
0
Sample Output
0 1
解题思路

这题由于数据范围很小,直接暴力枚举每一个A,B的值,看看在直线上方和下方的点的数量是不是都等于n

AC代码
#include<cstdio>

using namespace std;

const int N = 1E3 + 10;
int x[N], y[N], n;

void solve() {
	for(int i = -500; i <= 500; i++) {
		for(int j = -500; j <= 500; j++) {
			int sum1 = 0, sum2 = 0;
			for(int k = 1; k <= n; k++) {
				if(x[k] * i + y[k] * j > 0) sum1++;
				else if(x[k] * i + y[k] * j < 0) sum2++;
			}
			if(sum1 == n / 2 && sum2 == n / 2) {
				printf("%d %d\n", i, j);
				return ;
			}
		}
	}
}

int main() {
	while(~scanf("%d", &n) && n != 0) {
		n <<= 1;
		for(int i = 1; i <= n; i++) {
			scanf("%d%d", x + i, y + i);
		}
		solve();
	}
	return 0;
} 

B - Is This Integration ?

Description

In the image below you can see a square ABCD, where AB = BC = CD = DA = a. Four arcs are drawn taking the four vertexes A, B, C, D as centers and a as the radius. The arc that is drawn taking A as center, starts at neighboring vertex B and ends at neighboring vertex D. All other arcs are drawn in a similar fashion. Regions of three different shapes are created in this fashion. You will have to determine the total area if these different shaped regions

Input

The input file contains a floating-point number a (0 ≤ a ≤ 10000) in each line which indicates the length of one side of the square. Input is terminated by end of file.

Output

For each line of input, output in a single line the total area of the three types of region (filled with different patterns in the image above). These three numbers will of course be floating point numbers with three digits after the decimal point. First number will denote the area of the striped region, the second number will denote the total area of the dotted regions and the third number will denote the area of the rest of the regions.

Sample Input
0.1
0.2
0.3
Sample Output
0.003 0.005 0.002
0.013 0.020 0.007
0.028 0.046 0.016
解题思路

这题就是去找几个面积之间的关系,然后根据先后顺序去求即可

AC代码
#include<cstdio>
#include<cmath>

using namespace std;


int main() {
	double a;
	double pi = acos(-1.0);
	while(~scanf("%lf", &a)) {
		double s = a * a;
		double sx = s - (sqrt(3.0) / 4 *  s) - pi * s / 6;
		double sy = s - pi * s / 4 - 2 * sx;
		double sz = s - 4 * sx - 4 * sy;
		printf("%.3f %.3f %.3f\n", sz, 4 * sy, 4 * sx);
	}
	return 0;
} 

C - Simple division

Description

Integer division between a dividend n and a divisor d yields a quotient q and a remainder r. q is the integer which maximizes q ∗ d such that q ∗ d ≤ n and r = n − q ∗ d. For any set of integers there is an integer d such that each of the given integers when divided by d leaves the same remainder

Input

Each line of input contains a sequence of nonzero integer numbers separated by a space. The last number on each line is 0 and this number does not belong to the sequence. There will be at least 2 and no more than 1000 numbers in a sequence; not all numbers occuring in a sequence are equal. The last line of input contains a single 0 and this line should not be processed.

Output

For each line of input, output the largest integer which when divided into each of the input integers leaves the same remainder.

Sample Input
701 1059 1417 2312 0
14 23 17 32 122 0
14 -22 17 -31 -124 0
0
Sample Output
179
3
3
解题思路

因为这题要求所有的数去除一个数 d 然后余数相同,那就相当于所有的数都可以写成 q ∗ d + r q * d + r qd+r

由于我们要求的是 d d d, 所以直接让每一个数都和另外的数做差,然后去求最大公约数即可

AC代码
#include<cstdio>
#include<algorithm>

using namespace std;
const int N = 1e4 + 10;
int a[N], cnt, b[N], cnt2;

int gcd(int x, int y) {
	return y == 0 ? x : gcd(y, x % y);
}

int main() {
	int x;
	while(1) {
		scanf("%d", &x);
		if(x == 0) break;
		cnt = 0; cnt2 = 0;
		while(x != 0) {
			a[cnt++] = x;
			scanf("%d", &x);
		}
		for(int i = 1; i < cnt; i++) {
			if(a[i] == a[i - 1]) continue;
			if(a[i] < a[i - 1]) b[cnt2++] = a[i - 1] - a[i];
			else b[cnt2++] = a[i] - a[i - 1];
		}
		if(a[0] < a[1]) b[cnt2++] = a[1] - a[1];
		else if(a[0] > a[1]) b[cnt2++] = a[0] - a[1];
		int minn = 0x3f3f3f3f;
		for(int i = 0; i < cnt2; i++) {
			for(int j = i + 1; j < cnt2; j++) {
				minn = min(gcd(b[i], b[j]), minn);
			}
		}
		if(minn == 0x3f3f3f3f) {
			printf("1\n");
		} else {
			printf("%d\n", minn);
		}
		
	}
	return 0;
} 

D - Euclid Problem

Description

From Euclid it is known that for any positive integers A and B there exist such integers X and Y that AX + BY = D, where D is the greatest common divisor of A and B. The problem is to find for given A and B corresponding X, Y and D.

Input

The input will consist of a set of lines with the integer numbers A and B, separated with space (A, B < 1000000001).

Output

For each input line the output line should consist of three integers X, Y and D, separated with space. If there are several such X and Y , you should output that pair for which |X| + |Y | is the minimal. If there are several X and Y satisfying the minimal criteria, output the pair for which X ≤ Y .

Sample Input
4 6
17 17
Sample Output
-1 1 2
0 1 17
解题思路

这题直接扩展的欧几里得算法模板

AC代码
#include<cstdio>
#include<algorithm>

using namespace std;

int exgcd(int a, int b, int &x, int &y) {
	if(b == 0) {
		x = 1; y = 0;
		return a;
	}
	int t = exgcd(b, a % b, x, y);
	int x0 = x, y0 = y;
	x = y0, y = x0 - (a / b) * y0;
	return t;
}

int main() {
	int a, b, x, y;
	while(~scanf("%d%d", &a, &b)) {
		int t = exgcd(a, b, x, y);
		printf("%d %d %d\n", x, y, t);
	}
	return 0;
}

E - Dead Fraction

Description

Mike is frantically scrambling to finish his thesis at the last minute. He needs to assemble all his research notes into vaguely coherent form in the next 3 days. Unfortunately, he notices that he had been extremely sloppy in his calculations. Whenever he needed to perform arithmetic, he just plugged it into a calculator and scribbled down as much of the answer as he felt was relevant. Whenever a repeating fraction was displayed, Mike simply reccorded the first few digits followed by “…”. For instance, instead of “1/3” he might have written down “0.3333…”. Unfortunately, his results require exact fractions! He doesn’t have time to redo every calculation, so he needs you to write a program (and FAST!) to automatically deduce the original fractions.
To make this tenable, he assumes that the original fraction is always the simplest one that produces the given sequence of digits; by simplest, he means the the one with smallest denominator. Also, he assumes that he did not neglect to write down important digits; no digit from the repeating portion of the decimal expansion was left unrecorded (even if this repeating portion was all zeroes).

Input

There are several test cases. For each test case there is one line of input of the form “0.dddd…” where dddd is a string of 1 to 9 digits, not all zero. A line containing 0 follows the last case.

Output

For each case, output the original fraction.

Sample Input
0.2...
0.20...
0.474612399...
0
Sample Output
2/9
1/5
1186531/2500000
Hint
2/9
1/5
1186531/2500000
解题思路

这题去枚举循环节的长度,然后利用小数转化分数的公式求解即可

AC代码
#include<cstdio>
#include<cstring>

using namespace std;

int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
}

char s[20];

int main() {
	int n;
	char c;
	while(1) {
		scanf("%d%c", &n, &c);
		if(c == '\n') break;
		scanf("%s", s);
		int len = strlen(s);
		int x = 0, y = 1;
		int minn = 0x3f3f3f3f;
		int ansx = 0, ansy = 0;
		for(int i = 0; i < len - 3; i++) {
			x = x * 10 + (s[i] - '0');
			y *= 10;
		}
		int t = 1;
		for(int i = 1; i <= len - 3; i++) {
			t *= 10;
			int tx = x - (x / t);
			int ty = (y / t) * (t - 1);
			int g = gcd(tx, ty);
			tx /= g; ty /= g;
			if(ty >= minn) continue;
			minn = ty;	
			ansx = tx;
			ansy = ty;
		}
		printf("%d/%d\n", ansx, ansy);
	}
	return 0;
}

F - What is the Probability ?

Description

Probability has always been an integrated part of computer algorithms. Where the deterministic algorithms have failed to solve a problem in short time, probabilistic algorithms have come to the rescue. In this problem we are not dealing with any probabilistic algorithm. We will just try to determine the winning probability of a certain player. A game is played by throwing a dice like thing (it should not be assumed that it has six sides like an ordinary dice). If a certain event occurs when a player throws the dice (such as getting a 3, getting green side on top or whatever) he is declared the winner. There can be N such player. So the first player will throw the dice, then the second and at last the N-th player and again the first player and so on. When a player gets the desired event he or she is declared winner and playing stops. You will have to determine the winning probability of one (The I-th) of these players.

Input

Input will contain an integer S (S ≤ 1000) at first, which indicates how many sets of inputs are there. The next S lines will contain S sets of inputs. Each line contain an integer N (N ≤ 1000) which denotes the number players, a floating point number p which indicates the probability of the happening of a successful event in a single throw (If success means getting 3 then p is the probability of getting 3 in a single throw. For a normal dice the probability of getting 3 is 1/6), and I (I ≤ N) the serial of the player whose winning probability is to be determined (Serial no varies from 1 to N). You can assume that no invalid probability § value will be given as input.

Output

For each set of input, output in a single line the probability of the I-th player to win. The output floating point number will always have four digits after the decimal point as shown in the sample output.

Sample Input
2
2 0.166666 1
2 0.166666 2
Sample Output
0.5455
0.4545
解题思路

通过等比数列求和还有极限的知识去求解

AC代码
#include<cstdio>
#include<cmath>
#include<cstring>

using namespace std;
const double esp = 1e-9;

int main() {
	int t, n, i;
	double p;
	scanf("%d", &t);
	while(t--) {
		scanf("%d%lf%d", &n, &p, &i); 
		if(p < esp) printf("0.0000\n");
		double ans = pow(1 - p, i - 1.0) * p / (1.0 - pow(1.0 - p, n));
		printf("%.4f\n", ans);
	}
	return 0;
}

G - Burger

Description

When Mr. and Mrs. Clinton’s twin sons Ben and Bill had their tenth birthday, the party was held at the McDonald’s restaurant at South Broadway 202, New York. There were 20 kids at the party, including Ben and Bill. Ronald McDonald had made 10 hamburgers and 10 cheeseburgers and when he served the kids he started with the girl directly sitting left of Bill. Ben was sitting to the right of Bill. Ronald flipped a (fair) coin to decide if the girl should have a hamburger or a cheeseburger, head for hamburger, tail for cheeseburger. He repeated this procedure with all the other 17 kids before serving Ben and Bill last. Though, when coming to Ben he didn’t have to flip the coin anymore because there were no cheeseburgers left, only 2 hamburgers. Ronald McDonald was quite surprised this happened, so he would like to know what the probability is of this kind of events. Calculate the probability that Ben and Bill will get the same type of burger using the procedure described above. Ronald McDonald always grills the same number of hamburgers and cheeseburgers.

Input

The first line of the input-file contains the number of problems n , followed by n times: a line with an even number [2,4,6,…,100000], which indicates the number of guests present at the party including Ben and Bill.

Output

The output consists of n lines with on each line the probability (4 decimals precise) that Ben and Bill get the same type of burger. Note: a variance of ±0.0001 is allowed in the output due to rounding differences.

Sample Input
3
6
10
256
Sample Output
0.6250
0.7266
0.9500
解题思路

这题由于是让你求最后两个人吃相同类型的食物的概率,但是直接求的话,你不知道到什么时候发完一种类型的食物,也就是说什么时候不再判断,因此比较麻烦,我们可以采用逆向思维,去求吃不相同的食物的概率。

既然是不相同,所以前面 n − 2 n - 2 n2 个人中选择 (n / 2 - 1) 个人去吃一种,另外一半去吃另外一种,也就是
c n − 2 n / 2 − 1 2 n − 2 c_{n-2}^{n / 2 - 1} \over {2 ^ {n - 2}} 2n2cn2n/21
由于直接求组合数会爆数据范围,因此我们化简一下这个式子

就可以得到我们代码中的递推关系

AC代码
#include<cstdio>
#include<cmath>
#include<cstring>

using namespace std;
const int N = 1E5 + 7;

double a[N];

void cal() {
	a[2] = 1;
	for(int i = 4; i <= N; i += 2) {
		a[i] = a[i - 2] * (i - 3.0) / (i - 2.0); 
	}	
}

int main() {
	cal();
	int t, n;
	scanf("%d", &t);
	while(t--) {
		scanf("%d", &n);
		printf("%.4f\n", 1 - a[n]);
	}
	return 0;
}

I - 498-bis

Description

Looking throw the “Online Judge’s Problem Set Archive” I found a very interesting problem number 498, titled “Polly the Polynomial”. Frankly speaking, I did not solve it, but I derived from it this problem.

Everything in this problem is a derivative of something from 498. In particular, 498 was “… designed to help you remember … basic algebra skills, make the world a better place, etc., etc.”. This problem is designed to help you remember basic derivation algebra skills, increase the speed in which world becomes a better place, etc., etc.

In 498 you had to evaluate the values of polynomial
a 0 x n + a 1 x n − 1 + . . . + a n − 1 x + a n a_0x^n + a_1x^{n - 1}+...+a_{n - 1}x + a_n a0xn+a1xn1+...+an1x+an
In this problem you should evaluate its derivative. Remember that derivative is defined as
a 0 n x n − 1 + a 1 ( n − 1 ) x n − 2 + . . . + a n − 1 a_0nx^{n-1} + a_1(n-1)x^{n - 2}+...+a_{n - 1} a0nxn1+a1(n1)xn2+...+an1

All the input and output data will fit into integer, i.e. its absolute value will be less than 231 .

Input

Your program should accept an even number of lines of text. Each pair of lines will represent one problem. The first line will contain one integer - a value for x. The second line will contain a list of integers a0, a1, …, an−1, an, which represent a set of polynomial coefficients. Input is terminated by EOF

Output

For each pair of lines, your program should evaluate the derivative of polynomial for the given value x and output it in a single line

Sample Input
7
1 -1
2
1 1 1
Sample Output
1
5
解题思路

因为这题不知道要输入多少个数,因此不能直接用数组存,所以需要去找规律

去写一下第 i 项和 第 i+1 项,就可以发现这题的规律

然后可以边输入边求解

AC代码
#include<cstdio>
#include<cmath>

using namespace std;

int main() {
	int x, a;
	char c;
	while(~scanf("%d", &x)) {
		int sum = 0;
		int ans = 0;
		while(~scanf("%d", &a)) {	
			ans = ans * x + sum;
			sum = sum * x + a;		
			scanf("%c", &c);
			if(c == '\n') break;
		}
		printf("%d\n", ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值