1. 난수
난수 n개를 발생시키고 합과 평균을 출력하라. 사용자에게 원하는 범위의 시작과 끝을 입력받아 조건에 맞는 수가 출력되도록 작성하라.
<실행화면>
<소스코드>
// 프로그래밍랩 5주
// Lab5-1 난수 n개 (start ~ end) 발생시키고 합과 평균 출력
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main()
{
int i, n, r, sum = 0;
int start, end;
srand(time(NULL)); // 난수값 초기화
//srand(0);
printf("난수의 개수: ");
scanf("%d", &n);
printf("시작과 끝 : ");
scanf("%d %d", &start, &end);
int range = end - start + 1; //range = 101
for (i = 0; i < n; i++) {
r = rand() % range + start;
printf("%d ", r);
sum += r;
}
printf("\nsum=%d avg=%d\n", sum, sum / n);
}
2. 주사위 확률 계산
(1) 주사위를 n번 굴려서 나오는 수 1~6의 빈도수와 확률을 계산하여 출력하라.
(2) 주사위를 굴렸을 때 나오는 번호들은 각 1/6(~17%)의 확률을 갖는다. 이때, 번호가 나오는 확률이 조작되어 있는 이상한 주사위가 있다고 가정하고, 1~5는 각 10%, 6은 50%가 나오는 주사위를 만들어라. 확률을 조작하기 위해서는 rand() 함수를 이용해 범위를 지정한 후, 1, 2, 3, 4, 5, 6을 각각 구간으로 변경하면 된다.
<실행화면>
<소스코드>
// 프로그래밍랩 5주
// Lab5-2 주사위
// (1) n번 던져서 각각의 수의 발생 확률 계산해 보기
// (2) 확률이 조작된 주사위
// 1~5 = 10%, 6 = 50% 즉, 6이 자주 나오는 주사위
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main()
{
int i, r, ntest, dice;
int count[6] = {0}; // 1 ~ 6 count 를 보관
srand(time(NULL)); // 난수 초기화
printf("주사위 횟수 : ");
scanf("%d", &ntest);
printf("정상적인 주사위\n");
for (i=0;i<ntest;i++) {
dice = rand() % 6; // dice = ?? 0~5 -> 주사위 1~6
count[dice]++; // count[?] = 발생 회수 증가, 완성할 것
}
for (i=0;i<6;i++) {
// 화면과 같이 출력
printf("%d : %d (%4.2lf%%)\n", i + 1, count[i], (double)count[i] / 100);
}
printf("\n");
// 이상한 주사위
printf("\n이상한 주사위 6이 50%% 확률\n");
for (i = 0;i < 6;i++)
count[i] = 0;
for (i=0;i<ntest;i++) {
r = rand() % 100; // 분포를 0~99로 구하고 0~9, 10~19, 20~29, 30~39, 40~49, 50~99 를
// 1, 2, 3, 4, 5, 6 으로 맵핑
if (r < 10)
dice = 0;
else if (r < 20)
dice = 1;
else if (r < 30)
dice = 2;
else if (r < 40)
dice = 3;
else if (r < 50)
dice = 4;
else if (r >= 50 && r < 100)
dice = 5;
// 발생 회수 증가
count[dice]++;
}
for (i=0;i<6;i++) {
// 화면과 같이 출력
printf("%d : %d (%4.2lf%%)\n", i + 1, count[i], (double)count[i] / 100);
}
}
3.Lotto 번호 발생기
Lotto 번호는 1~45 사이의 6개 수로 구성된다. rand() 함수를 이용하여 난수를 생성하고, 각 줄에서 중복되지 않도록 조건을 설정하라. 출력 형식에 맞게 오름차순으로 정렬하고, 6개를 출력할 때마다 개행되도록 해야 한다.
<실행화면>
<소스코드>
// 프로그래밍랩 5주
// Lab5-3 Lotto 출력
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void bubbleSort(int lotto[], int n) {
int i, j, tmp;
int changed; //불필요한 swap 확인할 변수
for (i = 0; i < n-1; i++) {
changed = 0;
for (j = 0; j < n - 1 - i; j++) {
if (lotto[j] > lotto[j + 1]) {
tmp = lotto[j + 1];
lotto[j + 1] = lotto[j];
lotto[j] = tmp;
changed = 1; //swap 발생했다는 의미
}
}
if (changed == 0) //swap 발생 X = 이미 오름차순 정렬된 상태이므로
break; //바로 탈출
}
}
void main()
{
int i, j, n, l;
int lotto[6] = { 0 };
srand(time(NULL));
printf("복권 매 수는 : ");
scanf("%d", &l);
while (l--) {
for (i = 0; i < 6; i++) {
n = rand() % 45 + 1; //난수 발생
for (j = 0; j < i; j++) { //중복 검사
if (n == lotto[j]) {
n = rand() % 45 + 1; //중복이면 난수 다시 생성
j = -1; //j 초기화해서 다음 loop(j++->j=0)에서 다시 검증하도록
}
}
lotto[i] = n; //중복 아니면 lotto 배열에 저장
}
bubbleSort(lotto, 6);
for (i = 0; i < 6; i++) { //순서대로 출력
printf("%02d ", lotto[i]);
}
printf("\n");
}
}
4. 모의 성적 데이터 발생-1
성적 처리 프로그램을 위한 테스트 데이터를 생성하고자 한다. n명의 성적을 발생시키고 각 성적별 빈도수와 %를 출력하라.
<실행화면>
<소스코드>
// 프로그래밍랩 5주
// Lab5-4 성적 발생하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main()
{
int i, j, n, r; //n: 난수의 개수, r: 난수
int sum = 0; // 총점
// 학점별 인원수 0:A+, 1:A, ... D, 8:F
char* grade_str[] = { "A+", "A ", "B+", "B ", "C+", "C ", "D+", "D ", "F " };
int grade_index, grade_count[9] = { 0 };
int* scores[9];
//int score1;
scanf("%d", &n);
/*for (i = 0; i < 9;i++)
scores[i] = (int*)malloc(sizeof(int) * n);
if (scores == NULL) {
printf("동적할당 실패\n");
return -1;
}*/
srand(time(NULL)); // 난수 초기화
for (i = 0; i < n; i++) {
r = rand() % 101; // score1 = 0~100
printf("%d ", r);
sum += r; // sum 을 구한다.
// grade_index 를 구한다. 0:A+, 1:A ...
if (r >= 95) grade_index = 0; // A+
else if (r >= 90) grade_index = 1; // A
else if (r >= 85) grade_index = 2; // B+
else if (r >= 80) grade_index = 3; // B
else if (r >= 75) grade_index = 4; // C+
else if (r >= 70) grade_index = 5; // C
else if (r >= 65) grade_index = 6; // D+
else if (r >= 60) grade_index = 7; // D
else grade_index = 8; // F
// grade_count[]를 증가시킨다.
grade_count[grade_index]++;
}
printf("\n\nn=%d 평균 = %.2f\n", n, ((double)sum) / n);
for (i = 0; i < 9; i++) {
// 화면과 같이 출력
printf("%s : %5d (%6.2lf%%)", grade_str[i], grade_count[i], 100.0 * grade_count[i] / n);
printf("\n");
}
//free(scores);
}
5. 모의 성적 데이터 발생-2
성적 분포가 주어졌을 때 모의 데이터를 발생시킨다.
A+: 10%, A: 10%, B+: 20%, B: 25%, C+: 15%, C: 10%, D+: 5%, D: 3%, F: 2%
주사위 확률 조작 방법과 같은 방법으로 A+~F에 해당하는 점수를 발생시키고, 각 학점별 % 분포가 학생 수(정수)로 환산할 때 정확하게 일치하지 않을 수 있으므로 소수점으로 나오는 경우 보정해야 한다.
<실행화면>
<소스코드>
// 프로그래밍랩 5주
// Lab5-5 150명 성적 분포에 맞게 점수 발생시키기
// A+(95~100): 10%, A(90~94):10%, B+(85~89):20%, B(80~84):25%,
// C+(75~79):15%, C(70~74):10%, D+(65~69):5%, D(60~64):3%, F:2%
// Lab5-4와 강의노트 참조하여 작성
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void main()
{
int i, nstudents, prob, score; //prob: 각 등급에 배정할 학생 수(정수)
int j, sum = 0; //추가한 변수
char* grade_str[] = { "A+", "A ", "B+", "B ", "C+", "C ", "D+", "D ", "F " };
//int grade; //0~8, A+~F
int count[9] = { 0 }; //0~8, A~F+ 인원수
int maxcount[9] = { 10, 10, 20, 25, 15, 10, 5, 3, 2 }; //미리 계산된 최대 인원
int start[9] = { 95, 90, 85, 80, 75, 70, 65, 60, 0 }; //점수 시작
int end[9] = { 100, 94, 89, 84, 79, 74, 69, 64, 59 }; //점수 끝
scanf("%d", &nstudents);
srand((unsigned)time(NULL));
for (i = 0; i < 9; i++) {
prob = (int)round(nstudents * (maxcount[i] / 100.0)); //학점별 인원수 사전 설정. i 증가할 때마다 갱신
for (j = 0; j < prob; j++) { //제한된 인원수만큼 난수 발생
score = start[i] + rand() % (end[i] - start[i] + 1);
count[i]++;
sum += score;
printf("%d ", score);
}
}
printf("\n\nn=%d 평균 = %.2lf\n", nstudents, (double)sum / nstudents);
for (i = 0; i < 9; i++) {
printf("%s : %5d (%6.2lf%%)\n", grade_str[i], count[i], 100.0 * count[i] / nstudents);
}
}
6. 문장의 알파벳 분포 조사
input.txt를 읽어서 알파벳들의 문자수를 count하여 분표를 표시하라.
<실행화면>
<소스코드>
// 프로그래밍랩 5주
// Lab5-6 영문 TEXT 의 알파벳 빈도수 check
// input.txt 를 입력으로 받고, 아파벳들을 count하여 등장하는 확률을 표시
// 입력의 끝(keyboard 에서는 CTRL-Z) EOF로 검사를 한다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//#include <windows.h>
void main()
{
char c;
int total = 0; // 전체 입력 수(영문자, 숫자, 공백, 특수문자 전부 포함됨)
int alpha = 0; // 알파벳 문자수
int blank = 0; // blank(space, tab, newline) 문자수
int digit = 0; // 0~9 문자수
int special = 0; // 특수문자 수
int count[26] = { 0 };//알파벳별로 count
while ((c = getchar()) != EOF) { // 입력의 끝이 아니면 알파벳 카운트
total++;
if (isalpha(c)) { // 알파벳만 검사
c = toupper(c);
alpha++;
count[c - 'A']++;
}
else if (isspace(c)) blank++; // whitespace 이면
else if (isdigit(c)) digit++; // 숫자이면
else special++;
}
printf("\n\n전체문자수=%d 알파벳수=%d\n", total, alpha);
for (c = 'A'; c <= 'Z'; c++) {
// 화면과 같이 출력
printf("%c:%-3d (%5.2lf%%) ", c, count[c - 'A'], count[c - 'A'] * 100.0 / total);
if ((c - 'A') % 5 == 4) printf("\n"); // 인덱스 번호가 4의 배수이면 개행
}
printf("\n");
//Sleep(50000);
}
7. 3개의 주사위 통계
난수를 이용하여 주사위 3개의 합(3~18)을구하고 그 분포를 화면과 같이 Histogram으로 표시하는 프로그램을 작성하시오. 주사위 합은 30,000번 구한다. 화면과 같이 분포는 소수점 2자리, Histogram은 1%당 1개씩 *를 표시하며 소수점이 존재하면 한 개씩 더 출력한다. (eg. 1.36%의 경우 2개의 *가 표시되고 10.00%의 경우 10개만 표시된다.)
<실행화면>
<소스코드>
// Lb5-7 주사위 3개 통계
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void main()
{
// 필요하면 변수 추가
//int r1, r2;
int dice[19] = { 0 }; //dice[0]~dice[2]는 버려지는 공간
int n, i, j, hist;
int sum;
double perc = 0;
// 난수 초기화
srand((unsigned)time(NULL));
// 30000번 동안 주사위 3개 합을 구해 dice[] 값을 증가시킨다.
for (i = 0; i < 10000; i++) {
sum = 0;
for (j = 0; j < 3; j++) {
n = rand() % 6 + 1;
sum += n;
}
dice[sum]++;
}
// Histogram을 출력한다.
// *의 수는 소숫점이 있으면 +1개 출력한다.
for (i = 3; i <= 18; i++) {
perc = 100.0 * dice[i] / 10000;
hist = ceil(perc);
printf("%2d: %5.2lf%% ", i, perc);
for (j = 0; j < hist; j++)
printf("*");
printf("\n");
}
}
8. 수학 공부 프로그램
난수를 이용하여 어린 조카의 수학 공부를 위한 덧셈(x + y) 학습 프로그램을 작성한다. 다음 조건을 확인하여 프로그램하시오.
<실행화면>
<소스코드>
// 덧셈 공부
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void main()
{
int x, y, r, result, ans; // 필요하면 변수 추가
int round = 0, ok = 0; // round: 총 라운드 수, ok: 맞힌 문항 수
srand((unsigned)time(NULL)); // 난수 초기화
while (1) { // 무한 반복
r = rand() % 100;
// x+y 를 확률에 따라 1자리, 2자리, 3자리 문제를 출력한다.
if (r < 30) { // 30% 확률
x = rand() % 10 + 1;
y = rand() % 10 + 1;
}
else if (r < 90) { // 60% 확률
x = rand() % 90 + 10;
y = rand() % 100 + 10;
}
else { // 10% 확률
x = rand() % 900 + 100;
y = rand() % 900 + 100;
}
result = x + y;
printf("(문제 %d) %d + %d = ", ++round, x, y);
scanf("%d", &ans); // ans 입력
if (ans == 0) // ans 가 0이면 반복 종료
break;
if (ans == result) { // 정답과 오답 결과 출력
printf("정답입니다.\n");
ok++;
}
else
printf("틀렸습니다.\n");
} // 반복끝
// 정답률 출력
printf("정답률: %.0lf%% (%d/%d)\n", 100.0 * ok / round, ok, round);
}
ACM. 괄호 검증 - VPS
중첩된 괄호 ( ) 의 유효성을 검사한다. 올바른 괄호 문자열 VPS(Vaild Parenthesis String)인지 확인하여 YES/NO를 출력한다. ')'가 먼저 나오거나 '('로 끝나는 경우도 확인하라.
<실행화면>
<소스코드>
// 프로그래밍랩
// 5주 ACM 문제
// VPS (Valid Parantesis String) 검증
// () 의 짝이 맞으면 YES, 틀리면 NO
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
//#include <windows.h>
//#include <time.h>
void main()
{
int ntest;
char buf[100];
int i, len;
int count1 = 0, count2 = 0;
scanf("%d", &ntest);
while (ntest--) {
scanf("%s", buf); // 1라인 입력
count1 = count2 = 0;
len = strlen(buf);
// ')'가 먼저 나오거나 '('로 끝나는 경우 확인
if (buf[0] == ')'|| buf[len-1] == '(')
printf("NO\n");
// 문자열을 모두 검사해서 '(' 갯수와 ')' 갯수를 count하고
for (i = 0; i < len; i++) {
if (buf[i] == '(')
count1++;
else if (buf[i] = ')')
count2++;
}
// count1 count2 를 비교하여 판단
(count1 == count2) ? printf("YES\n") : printf("NO\n");
}
//Sleep(10000);
}
[프로그래밍랩] 6주차 - Quiz (0) | 2025.04.14 |
---|---|
[프로그래밍랩] 5주차 - Quiz (0) | 2025.04.13 |
[프로그래밍랩] 4주차 - 재귀함수 (0) | 2025.04.06 |
[2025 코딩캠프] #5 포인터와 제어문으로 직선의 방정식 구하기 (lv.2) (0) | 2025.01.23 |
[2025 코딩캠프] #2 1부터 10까지 중간합과 누적합 출력하기 (lv.2) (0) | 2025.01.23 |