C 언어 알고리즘 학습 (수학적 알고리즘, 유클리드, 확률 이론)

오늘은 네 문제 만 풀 었는데 불편 해요

해결

생일 케이크

문제 수정 :

• Lucy와 Lily는 쌍둥이이고 오늘이 그들의 생일입니다. 어머니는 그들에게 생일 케이크를 사 주셨습니다. 이제 케이크는 데카르트 좌표계에 배치되고 케이크의 중심은 (0,0)에 있으며 케이크의 반지름은 100입니다.
• 케이크에는 2N (N은 정수, 1≤N≤50) 체리가 있습니다. 엄마는 칼로 케이크를 반으로자를 것입니다 (물론 일직선으로). 쌍둥이는 당연히 공정하게 취급되어야합니다. 즉, 케이크의 두 반쪽은 같은 모양이어야하며 (즉, 직선이 케이크의 중앙을 통과해야 함) 케이크의 각 반쪽에는 체리 N 개가 있어야합니다. 그녀를 도울 수 있습니까?
• 여기서 체리의 좌표 (x, y)는 두 개의 정수입니다. 이 행을 두 개의 정수 A, B (Ax + By = 0을 나타냄) 형식으로 제공하고 A와 B는 [-500, 500]에 있습니다. 체리는 일직선이 될 수 없습니다. 각 테스트 케이스에 대해 하나 이상의 솔루션이 있습니다.

시작하다

• 입력에 여러 테스트 케이스가 포함되어 있습니다. 각 테스트 케이스는 두 부분으로 구성됩니다. 첫 번째 부분은 한 줄에 숫자 N을 제공하고 두 번째 부분은 2N 줄로 구성되며 각 줄에는 (x, y)를 나타내는 두 개의 숫자가 있습니다. 두 숫자 사이에는 공백이 하나만 있습니다. 입력은 N = 0으로 끝납니다.

산출

• 각 테스트 케이스에 대해 두 숫자 사이에 공백을두고 두 숫자 A와 B를 제공하는 한 줄을 출력합니다. 솔루션이 여러 개인 경우 그중 하나만 출력하십시오.

질문 분석

•이 질문의 첫 번째 줄에 N을 입력합니다. 이는 케이크에 2N 체리가 있음을 의미합니다. 다음 2N 행 각각은 체리의 좌표를 제공합니다. 케이크는 원점이 중심이고 반경이 100 인 원이므로 좌표 값의 범위는 [-100, 100]입니다. 이 질문의 출력은 직선 방정식 Ax + By = 0 A와 B이며 범위는 [-500, 500]입니다.
•이 질문은 열거 방법을 채택하고 [-500, 500] 범위의 A와 B를 열거하고 체리 좌표를 선형 방정식 Ax + By로 대체합니다. Ax + By가 0보다 크면 체리가 0보다 작 으면 체리가 직선 아래에 있고 0과 같으면 체리가 직선에있을 수 없기 때문에 허용되지 않습니다. 첫 번째 솔루션이 생성 될 때까지 열거합니다.

소스 코드

#include <iostream>

using namespace std;

const int LEFT = -500, RIGHT = 500;
const int N = 50;
int x[N * 2], y[N * 2];

int main()
{
    
    
    int n;
    while(~scanf("%d", &n) && n) {
    
    
        n *= 2;

        for(int i = 0; i < n; i++)
            scanf("%d%d", &x[i], &y[i]);

        bool flag = true;
        for(int a = LEFT; a <= RIGHT && flag; a++)
            for(int b = LEFT; b <= RIGHT ; b++) {
    
    
                if(a==0 && b==0 ) continue;
                int i, cnt = 0;     // 统计满足AX+BY>0的点数目
                for(i = 0; i < n; i++) {
    
    
                    if(a * x[i] + b * y[i] > 0) ++cnt;
                    else if(a * x[i] + b * y[i] == 0) break;
                }
                if( i < n) continue;
                if(cnt == n / 2) {
    
    
                    printf("%d %d\n", a, b);
                    flag = false;
                    break;
                }
            }
    }

    return 0;
}

B이 통합입니까?

문제 수정

그림에는 정사각형 ABCD가 있습니다. 여기서 AB = BC = CD = DA = a입니다. 4 개의 정점 A, B, C, D를 중심으로, a를 반지름으로 사용하여 4 개의 호를 그립니다. 중심이 A 인 호는 인접한 정점 B에서 시작하여 인접한 정점 D에서 끝납니다. 다른 모든 호 비슷한 방식으로 그려집니다. 그림과 같이 사각형 안에 세 개의 서로 다른 모양의 영역이 그려지며 각 영역은 서로 다른 음영으로 표현됩니다. 다른 음영 부분의 총 면적을 계산하십시오.
여기에 사진 설명 삽입

시작하다

• 각 입력 라인에는 사각형 변의 길이를 나타내는 부동 소수점 숫자 a (0 <a <10000)가 지정됩니다. 입력은 EOF로 끝납니다.

산출

• 입력의 각 줄에 대해 한 줄을 출력하여 세 가지 음영 부분의 총 면적을 제공합니다.
소수점 세 자리의 부동 소수점 숫자 세 개를 제공하고 첫 번째 숫자는 줄무늬 영역의 전체 면적을 나타냅니다. 두 번째 숫자는 점선 영역의 전체 면적을 나타내고 세 번째 숫자는 나머지 영역의 면적을 나타냅니다.

샘플 입력

0.1
0.2
0.3

샘플 출력

0.003 0.005 0.002
0.013 0.020 0.007
0.028 0.046 0.016

문제 해결

여기에 사진 설명 삽입

질문 분석

•이 질문은 정사각형의 변 길이 a를 제공하고 세 가지 음영 부분의 총 면적을 계산해야합니다. 그림과 같이 보 조선이있는 정삼각형을 그리면 세 가지 음영 부분의 영역이 x, y 및 z로 표시됩니다.

소스 코드

#include<iostream>
#include<cmath>
using namespace std;
const double pi=acos(-1);
int main() {
    
    
	double a;
	while(cin>>a) {
    
    
		double z=a*a-pi*a*a/6.0-sqrt(3.0)/4.0*a*a;
		double y=(a*a-pi*a*a/4.0-2.0*z);
		double x=(a*a-4.0*y-4.0*z);
		printf("%.3lf %.3lf %.3lf\n",x,y*4.0,z*4.0);
	}
}/*
        double z = r * r * (1 - PI / 6.0 - sqrt(3.0) / 4);
        double y = r * r * (1 - PI / 4.0 ) - 2 * z;
        double x = r * r  * (PI / 2.0 - 1) - 2 * y;
		*/

C 단순 나눗셈

문제 수정

여기에 사진 설명 삽입
피제수 n과 제수 d 사이의 정수 나누기 연산은 몫 q와 나머지 r을 생성합니다. q는 q d ≤ n 및 r = n-q * d가 되도록 q d 최대화 하는 정수입니다 .
• 정수 세트가 주어지면 주어진 정수를 d로 나눌 때 나머지는 동일하도록 정수 d가 있습니다.

시작하다

• 각 입력 행은 공백으로 구분 된 0이 아닌 정수 시퀀스를 제공합니다. 각 줄의 마지막 숫자는 0이며이 시퀀스에 속하지 않습니다. 시퀀스에는 최소 2 개, 최대 1000 개의 숫자가 있습니다. 시퀀스의 숫자가 모두 같지는 않습니다. 입력의 마지막 줄은 단일 0을 제공하며 프로그램은이 줄을 처리 할 필요가 없습니다.

산출

• 각 입력 라인에 대해 가장 큰 정수를 출력하여 입력의 각 정수를 나머지가 동일한 숫자로 나눕니다.

샘플 입력

701 1,059 1,417 2,312 0
14 23 17 32 122 0
14 17 -22 -31 -124 0
0

샘플 출력

179
3
3

문제 해결

소스 코드

#include <algorithm>
#include<iostream>
using namespace std;
int gcd(int x,int y) {
    
    
	int r;
	while (x%y!=0) {
    
    
		r=x%y;
		x=y;
		y=r;
	}
	return y;
}
int main() {
    
    
	int a1, a;
	while(~scanf("%d", &a1) && a1) {
    
    
		int g = 0;
		while(scanf("%d", &a) == 1 && a) {
    
    
			int d = a - a1;
			if(d) {
    
    
				if(g) g = gcd(g, d);
				else g = d;
			}
			a1 = a;
		}
		printf("%d\n", abs(g));
	}

	return 0;
}

G-버거

문제 수정

• 클린턴 가족의 쌍둥이 아들 인 Ben과 Bill은 10 주년을 맞이했으며 뉴욕의 202 South Broadway에있는 McDonald ’s 레스토랑에서 파티가 열렸습니다. 이 파티에는 벤과 빌을 포함한 20 명의 아이들이 참석했습니다. 로널드 맥도날드는 비프 버거 10 개와 치즈 버거 10 개를 만들어 아이들을 섬길 때 빌의 왼쪽에 앉아있는 소녀, 빌의 오른쪽에 앉아있는 벤으로 시작했습니다. Ronald는 소녀가 비프 버거를 먹을 것인지 치즈 버거를 먹을 것인지 결정하기 위해 동전을 던졌습니다. 동전의 머리 쪽은 비프 버거이고 반대는 치즈 버거입니다. Ben과 Bill의 차례가되기 전에 Ronald는 다른 17 명의 아이들과 함께 그 과정을 반복했습니다. Ronald가 Ben에 왔을 때 그는 더 이상 동전을 던질 필요가 없었습니다. 왜냐하면 치즈 버거가없고 쇠고기 버거가 두 개뿐 이었기 때문입니다.
• Ronald McDonald는 이것에 매우 놀랐습니다. 그래서 그는 이런 종류의 일이 일어날 확률을 알고 싶었습니다. 위의 과정에서 Ben과 Bill이 같은 버거를 먹을 확률을 계산하십시오. Ronald McDonald는 항상 같은 수의 쇠고기 버거와 치즈 버거를 굽습니다.

문제 분석

여기에 사진 설명 삽입
위의 그림에서 볼 수 있듯이 오프라인을 사용하여 해결할 수 있습니다. (최초 오프라인 방법 사용, 숙련되지 않음)

소스 코드

#include<iostream>
#include<cmath>
using namespace std;
const int N=5e4+7;
int cas,n;
double p[N];
void solve()
{
    
    
	p[1]=1;
	for(int i=1;i<N-1;++i)
		p[i+1]=(2*i-1)*p[i]/(2*i);
}
int main(){
    
    
	solve();
	cin>>cas;
	while(cas--){
    
    
		cin >>n;
		n/=2;
		printf("%.4lf\n",1-p[n]);
	}
	return 0;
}

해결되지 않은 부분

D-유클리드 문제

유클리드에서 모든 양의 정수 A와 B에 대해 X와 Y가 존재하는 것으로 알려져 있습니다. 여기서 D는 A와 B의 최대 공약수입니다. 문제는 주어진 A와 B에 해당하는 X를 찾는 것입니다. Y와 D.

입력

입력은 공백으로 구분 된 정수 A 및 B
(A, B <1000000001) 의 행 세트로 구성됩니다 .

산출

각 입력 라인에 대해 출력 라인은 공백으로 구분 된 세 개의 정수 X, Y 및 D로 구성되어야합니다.
이러한 X 및 Y가 여러 개있는 경우 | X | + | Y | 최소입니다. 최소 기준을 만족하는 X와 Y가 여러 개인 경우 X ≤ Y 인 쌍을 출력합니다.

샘플 입력

4 6
17 17

샘플 출력

-1 12
0 1 17

문제 분석

분명히이 문제는 확장 된 유클리드 알고리즘으로 해결해야합니다.

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;

}

하지만 저는 AC가 없어서 이유를 찾을 수 없습니다.

소스 코드

#include <cstdio>
#include <cmath>
#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 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, d;
	while(~scanf("%d%d", &a, &b)) {
    
    
		d = exgcd(a, b, x, y);
		printf("%d %d\n",x,y);
	}
	return 0;
}

F-확률은 무엇입니까?

확률은 항상 컴퓨터 알고리즘의 통합 된 부분이었습니다. 결정 론적 알고리즘이 단시간에 문제를 해결하지 못한 경우 확률 적 알고리즘이 구출되었습니다. 이 문제에서 우리는 확률 알고리즘을 다루지 않습니다. 우리는 특정 플레이어의 승리 확률을 결정하려고 노력할 것입니다.
게임은 주사위를 던지는 방식으로 진행됩니다 (일반 주사위처럼 6면이 있다고 가정해서는 안됩니다). 플레이어가 주사위를 던질 때 특정 이벤트가 발생하면 (예 : 3을 얻거나 녹색면이 맨 위에 오거나 무엇이든) 승자가됩니다. 그런 플레이어가 N 명있을 수 있습니다. 그래서 첫 번째
플레이어는 주사위를 던지고 두 번째, 마지막으로 N 번째 플레이어, 다시 첫 번째 플레이어 등을 던집니다. 플레이어가 원하는 이벤트를 받으면 승자로 선언되고 플레이가 중지됩니다. 이 플레이어 중 한 명 (I-th)의 승리 확률을 결정해야합니다.

입력

입력은 처음에 정수 S (S ≤ 1000)를 포함하여 입력 세트의 수를 나타내며 다음 S 라인에는 S 세트의 입력이 포함됩니다. 각 줄에는 플레이어 수를 나타내는 정수 N (N ≤ 1000)이 포함되어 있습니다. 부동 소수점 숫자 p는 한 번의 던지기에서 성공한 이벤트가 발생할 확률을 나타냅니다 (성공이 3을 얻는다는 의미이면 p는 일반 주사위의 경우 3을 얻을 확률은 1/6이고 I (I ≤ N)는 승리 확률이 결정되는 플레이어의 일련 번호입니다 (일련 번호는 1에서 N까지 다양 함). 잘못된 확률 § 값이 입력으로 제공되지 않는다고 가정 할 수 있습니다.

산출

각 입력 세트에 대해 I 번째 플레이어가 이길 확률을 한 줄로 출력합니다. 출력
부동 소수점 숫자는 샘플
출력에 표시된대로 항상 소수점 뒤에 4 자리 숫자를 갖습니다 .

샘플 입력

2
2 0.166666 1
2 0.166666 2

샘플 출력

0.5455
0.4545

문제 분석

여기에 사진 설명 삽입
공식을 대체했는데 AC가 없어서 이유를 찾을 수 없습니다

소스 코드

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
    
    
	int N,i,n;
	double p;
	scanf("%d",&N);
	for(int j=0; j<N; j++) {
    
    
		cin >>n >>p >>i;
		float proba =(pow((1-p),i-1)*p/(1-pow((1-p),n)));
		printf("%.4f\n",proba);
	}
}

오늘도 아직 많은 문제가 남아 있는데 언제 해결할 시간이 있을지 모르겠습니다

추천

출처blog.csdn.net/seekerzhz/article/details/112910421