寒假集训1.20

寒假集训1.20

A - Birthday Cake

在这里插入图片描述

题目大意:均分蛋糕上的樱桃,不能偏心

思路:蛋糕上的所有樱桃看成点,拥有坐标,切口看成一条线,题目就转换成了系数要满足有n个点在直线上方,n个点在直线下方,直线上不能有点

主要代码:

for( i=-500;i<510;i++)
	{
		int num=0;
		
        for( j=-500;j<500;j++)
		{
			int num=0;  
                if(i==0&&j==0)
					continue;  
                for(  k=0;k<2*n;k++)  
                {  
                    if((i*p[k].x+j*p[k].y)>0)
						num++;  
                    if((i*p[k].x+j*p[k].y)==0)
						break;  
                }  
                if(k==2*n&&num==n)  
                {  
                    x=0;  
                    break;  
                }  
		}
		if(x==0)
			break;
	}

完整代码:

#include<iostream>
#include<stdio.h>
#include<cmath>
 
using namespace std;
struct note
{
	int x,y;
}p[500];
int main()
{
	int n,d,i=0,j,k;
	while(scanf("%d",&n)&&n)
	{
	for( i=0;i<2*n;i++)
	{
		scanf("%d%d",&p[i].x,&p[i].y);
	}
	int x=1;
	for( i=-500;i<510;i++)
	{
		int num=0;
		
        for( j=-500;j<500;j++)
		{
			int num=0;  
                if(i==0&&j==0)
					continue;  
                for(  k=0;k<2*n;k++)  
                {  
                    if((i*p[k].x+j*p[k].y)>0)
						num++;  
                    if((i*p[k].x+j*p[k].y)==0)
						break;  
                }  
                if(k==2*n&&num==n)  
                {  
                    x=0;  
                    break;  
                }  
		}
		if(x==0)
			break;
	}
	printf("%d %d\n",i,j); 
	}
}

B - Is This Integration ?

在这里插入图片描述
在这里插入图片描述

题目大意:求三种阴影部分的面积

思路:做辅助线方便找到公式[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YxvLoWOx-1611306381252)(C:\Users\29252\Pictures\题目\B1.png)]

要是让我自己做的话肯定想不到要做辅助线。。。还是做的题目太少了,经验不足,推出公式题目就很简单,推不出来,啥也不是。。

在这里插入图片描述

完整代码:

#include<iostream>
#include<cmath>
using namespace std;
double a;
#define PI acos(-1.0)
int main() {
	while (cin >> a) {
		printf("%.3f %.3f %.3f\n", a * a * (1 + PI / 3 - sqrt(3.0)),a * a * (PI / 3 + 2 * sqrt(3.0) - 4), a * a * (-2 * PI / 3 + 4 - sqrt(3.0)));
	}
	return 0;
}

C - Simple division

在这里插入图片描述

题目大意:根据给出的一系列数据,找出一个最大的整数,使输入的每一个整数除以该数字余数相同

思路:如果两个不同的数除以一个除数的余数相同,则这两个不同数的差值一定是除数的倍数。(刚开始自己真的想到)

利用差值枚举除数即可。所以要先求出原序列的一阶差分序列,然后求出所有非零元素的GCD

主要代码:

int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
}
while (true) {
		n = 0;
		ans = 0;
		cin >> f[++n];

		if (f[n] == 0)break;
		while (f[n] != 0) cin >> f[++n];
			n--;
		for (int i = 1; i < n; ++i) {
			f[i] = f[i] - f[i + 1];
		}

完整代码:

#include<iostream>
#include<cmath>
using namespace std;
const int N = 1e6 + 10;
int f[N];
int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
}
int  main() {
	int a, b,n,ans;
	while (true) {
		n = 0;
		ans = 0;
		cin >> f[++n];

		if (f[n] == 0)break;
		while (f[n] != 0) cin >> f[++n];
			n--;
		for (int i = 1; i < n; ++i) {
			f[i] = f[i] - f[i + 1];
		}
		ans = f[1];
		for (int i = 2; i < n; ++i) {
			ans = gcd(f[i] == 0 ? ans : f[i], ans);
		}
		cout << fabs(ans) << endl;
	}

	return 0;
}

D - Euclid Problem

知识点:拓展欧几里得算法

题目大意:由欧几里得的辗转相除法可知,对于任何正整数AB,都存在这样的整数XYAX+BY=D,其中DAB的最大公约数。本题要求,对于给定的A和B,找到对应的XYD

思路:利用扩展欧几里得算法求解

主要代码:

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

完整代码:

#include<iostream>

using namespace std;

int exgcd(int a, int b, int& x, int& y) {
	if (b == 0) {
		x = 1; y = 0;
		return a;
	}
	int d = exgcd(b, a % b, x, y);
	int tmp = x;
	x = y;
	y = tmp - (a / b) * y;
	return d;
}
int main() {
	int a, b;
	while (cin >> a >> b) {
		int x = 0, y = 0;
		int d = exgcd(a, b, x, y);
		cout << x << ' ' << y << ' ' << d << endl;
	}
	return 0;
}

E - Dead Fraction

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

题目大意:将循环小数转换为分数,如果循环部分有多种情况,就转化为分母最小的哪一个分数

在这里插入图片描述

思路:有理数可以写成m/n的形式,无限循环小数转分数(0.xxxx)小数部分n位,循环部分a位,非循环部分n-a位

分子:n*10^n -n/10^ a 分母:(10(a)-1)*(10(n-a))再通过gcd化简为最简分数

这题看了润哥的代码,他讲了之后才明白思路,自己做的时候不懂怎么实现小数准换成分数,没发现规律…

完整代码:

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
typedef long long ll;
ll z[11]={1};
string s;
void pre(){
	for(int i = 1;i<=10;++i)
	    z[i] = (z[i-1]<<3)+(z[i-1]<<1);
}
ll gcd(ll a,ll b){
	ll c;
	while(b){
		c=a%b;
		a=b;
		b=c;
	}
	return a;
}
int main(){
	pre();
	while((cin>>s)&&s.size()>1){
		ll num = 0;
		ll b =0;
		for(int i = 2;s[i]!='.';++i){
			num = num*10+s[i]-'0';
			b++;
		}
		ll minfz = -1;
		ll minfm = -1;
		ll fz,fm;
		for(int i = 1;i<=b;++i){
			fz  = num-num/z[i];
			fm = (z[i]-1)*z[b-i];
			ll g = gcd(fz,fm);
			if(fm/g < minfm||minfm==-1){
				minfz = fz/g;
				minfm = fm/g;
			}
		}
		printf("%lld/%lld\n",minfz,minfm);
	}
	
	return 0;
}

F - What is the Probability ?

在这里插入图片描述

题目大意:计算第i个玩家在第k轮赢的概率

思路:第i个玩家在第一轮赢,那么第i个玩家前的i-1个玩家没有赢,则第i个玩家第一轮赢的概率为(1-p)^(i-1)*p

同理第i个玩家在第k轮赢,赢的概率为(1-p)^{n(k-1)+i-1} *p,由加法原理和等比数列求和公式,推出第i个玩家获胜的概率为{(1-p)(i-1)*p}*(1/(1-(1-p)n))

完整代码:

#include<iostream>
#include<cmath>
using namespace std;
int s, x, i;
double p;
double ans;
int main() {
	cin >> s;
	while (s--) {
		cin >> x >> p >> i;
		if(p==0) ans = 0;
		else ans = pow(1 - p, i - 1) * p * (1.0 / (1 - pow(1 - p, x)));
		printf("%.4f\n", ans);
	}
	return 0;
}

G - Burger

在这里插入图片描述

题目大意:20个人参加派对,包括ben和bill,有10个牛肉汉堡,10个芝士汉堡,抛硬币,硬币头像为正面,抛的人吃牛肉的,反之吃芝士的,题目求ben和bill吃同一种汉堡的概率

思路:正面求的话,情况很多,所以求两人吃的汉堡不一样的概率

在这里插入图片描述

在这里插入图片描述

还是学长厉害,对这种递推题目了解的多,我自己做的时候有点思维不灵活性,没想到逆向思维推导

主要代码:

#include<iostream>
using namespace std;
const int N = 1e6+6;
int s,n;
double p[N];
int main(){
	cin>>s;
	p[1] = 1;
	for(int i = 1;i<1e6;++i)
	    p[i+1] = (2*i-1)*p[i]/(2*i);
	while(s--){
		cin>>n;
		n = n/2;
		printf("%.4f\n",1-p[n]);//反向思维 
	}
	return 0;
} 

H - Coin Toss

In a popular carnival game, a coin is tossed onto a table with an area that is covered with square tiles in a grid. The prizes are determined by the number of tiles covered by the coin when it comes to rest: the more tiles it covers, the better the prize. In the following diagram, the results from five coin tosses are shown:

img

In this example:

  • coin 1 covers 1 tile
  • coin 2 covers 2 tiles
  • coin 3 covers 3 tiles
  • coin 4 covers 4 tiles
  • coin 5 covers 2 tiles

Notice that it is acceptable for a coin to land on the boundary of the playing area (coin 5). In order for a coin to cover a tile, the coin must cover up a positive area of the tile. In other words, it is not enough to simply touch the boundary of the tile. The center of the coin may be at any point of the playing area with uniform probability. You may assume that (1) the coin always comes to a rest lying flat, and (2) the player is good enough to guarantee that the center of the coin will always come to rest on the playing area (or the boundary).

The probability of a coin covering a certain number of tiles depends on the tile and coin sizes, as well as the number of rows and columns of tiles in the playing area. In this problem, you will be required to write a program which computes the probabilities of a coin covering a certain number of tiles.

Input

The first line of input is an integer specifying the number of cases to follow. For each case, you will be given 4 integers m, n, t, and c on a single line, separated by spaces. The playing area consists of m rows and n columns of tiles, each having side length t. The diameter of the coin used is c. You may assume that 1 <= m, n <= 5000, and 1 <= c < t <= 1000.

Output

For each case, print the case number on its own line. This is followed by the probability of a coin covering 1 tile, 2 tiles, 3 tiles, and 4 tiles each on its own line. The probability should be expressed as a percentage rounded to 4 decimal places. Use the format as specified in the sample output. You should use double-precision floating-point numbers to perform the calculations. “Negative zeros” should be printed without the negative sign.

Separate the output of consecutive cases by a blank line.

Sample Input

3
5 5 10 3
7 4 25 20
10 10 10 4

Sample Output

Case 1:
Probability of covering 1 tile  = 57.7600%
Probability of covering 2 tiles = 36.4800%
Probability of covering 3 tiles = 1.2361%
Probability of covering 4 tiles = 4.5239%

Case 2:
Probability of covering 1 tile  = 12.5714%
Probability of covering 2 tiles = 46.2857%
Probability of covering 3 tiles = 8.8293%
Probability of covering 4 tiles = 32.3135%

Case 3:
Probability of covering 1 tile  = 40.9600%
Probability of covering 2 tiles = 46.0800%
Probability of covering 3 tiles = 2.7812%
Probability of covering 4 tiles = 10.1788%

题目大意:抛一枚硬币,计算硬币分别占据1,2,3,4块砖的概率

思路:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CkxoULSM-1611306381261)(C:\Users\29252\Pictures\题目\H.png)]

又是推导公式题,在我没看老师的讲解之前,真的感觉无从下手,题目理解了,不会计算硬币能够占据的面积

主要代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const double PI=acos(-1.0),eps=1e-8;
int main()
{
    int x,cnt=0;
    cin>>x;
    while(x--){
        double n,m,t,c,A[5];
        scanf("%lf%lf%lf%lf",&n,&m,&t,&c);
        A[0]=t*t*n*m;//棋盘面积 
        A[2] = c*(t-c)*(2*m*n-n-m)+c*(c/2.0)*(2*n+2*m-4);
		A[4] = (m-1)*(n-1)*(PI*c*c)/4.0;
		A[3] = (m-1)*(n-1)*c*c-(m-1)*(n-1)*(PI*c*c)/4.0;
		A[1] = A[0]-A[2]-A[3]-A[4];
        printf("Case %d:\n",++cnt);
        for(int i=1;i<=4;i++)
            printf("Probability of covering %d tile%s = %.4lf%%\n",i,(i==1)?" ":"s",A[i]/A[0]*100.0);
        printf("\n");
    }
    return 0;
}

I - 498-bis

在这里插入图片描述

题目大意:

根据给定的多项式求导

思路:这题难的地方在于没有给出输入的数字上限,无法用数组保存,我之前用的流输入,结果对,可能有部分地方没考虑全,提交错了,学长用的还是递推找规律,看了之后感觉自己太菜了。递推式:A(i+1)=A(i)*x+a1;

a0;

a0x+a1;

(a0x+a1)x+a2 = a0x^2+a1x+a2 求导->2a1x+a1

(a0x^2+a1x+a2)x+a3= a0x^3 +a1x^2+a2x+a3 ->求导 3a0x^2+2a1x+a2 ->(2a0x+a1)x+a0x^2+a1x+a2;

后一阶段的导数由前一阶段的导数和原函数组成

后一阶段相对于前一个阶段,多乘了一个 ,所以其导数就比前一阶段在系数上要多1

后一阶段的导数相对于前一阶段多了一个常数

完整代码:

#include<iostream>
#include<cmath>
using namespace std;

int main(){
	int x,a;
	char c;
	while(~scanf("%d",&x)){
		int sum=0,ans = 0;
		while(~scanf("%d",&a)){
			ans = ans*x+sum;
			sum = sum*x+a;
			scanf("%c",&c);
			if(c=='\n') break;
		}
		cout<<ans<<endl;
	}
} 

;

(a0x+a1)x+a2 = a0x^2+a1x+a2 求导->2a1x+a1

(a0x^2+a1x+a2)x+a3= a0x^3 +a1x^2+a2x+a3 ->求导 3a0x^2+2a1x+a2 ->(2a0x+a1)x+a0x^2+a1x+a2;

后一阶段的导数由前一阶段的导数和原函数组成

后一阶段相对于前一个阶段,多乘了一个 ,所以其导数就比前一阶段在系数上要多1

后一阶段的导数相对于前一阶段多了一个常数

完整代码:

#include<iostream>
#include<cmath>
using namespace std;

int main(){
	int x,a;
	char c;
	while(~scanf("%d",&x)){
		int sum=0,ans = 0;
		while(~scanf("%d",&a)){
			ans = ans*x+sum;
			sum = sum*x+a;
			scanf("%c",&c);
			if(c=='\n') break;
		}
		cout<<ans<<endl;
	}
} 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值