문제는다양한방법으로풀수있으며, 다음의풀이는여러해법중하나이다. [ 문제 1] 밀도구하기 질량밀도 이다. 물체의질량 M과부피 V가주어지면밀도는 M/V로구할수있다. 부피 여기서질량 M 과부피 V 는정수이지만 M/V 은실수가될수있기때문에 M 과 V 를받 을때실수로입력받는다. 물체의운동은액체의밀도와물체의밀도와비교를통해알수있다. - 액체의밀도 > 물체의밀도이면 UP - 액체의밀도 = 물체의밀도이면 STOP - 액체의밀도 < 물체의밀도이면 DOWN 해결방법 - 1 #include<stdio.h> int main() freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); double M, V, R; scanf("%lf%lf%lf",&m,&v,&r); // M 과 V 를실수형으로입력받는다. printf("%.2lf ",M/V); if(r>m/v) printf("up"); if(r==m/v) printf("stop"); if(r<m/v) printf("down"); // 액체의밀도 > 물체의밀도이면 UP // 액체의밀도 = 물체의밀도이면 STOP // 액체의밀도 < 물체의밀도이면 DOWN return 0; - 1 -
해결방법 2 #include <stdio.h> int main(void) FILE *fi = fopen("input.txt", "rt"); FILE *fo = fopen("output.txt", "wt"); int m, v, r; fscanf(fi, "%d %d %d", &m, &v, &r); if(r > (double)m/v) fprintf(fo, "%.2f %s", (double)m/v, "UP"); else if(r == (double)m/v) fprintf(fo, "%.2f %s", (double)m/v, "STOP"); else fprintf(fo, "%.2f %s", (double)m/v, "DOWN"); fclose(fi); fclose(fo); return 0; - 2 -
[ 문제2] 기상예보등급에따른야외활동여부입력된데이터를정해진규칙에따라연산하고그결과에따른활동여부를판단하는문제이다. 입력받은값을예보구간에따라등급을출력하고, 3개의예보등급중에가장높은등급으로야외활동여부를판단하여결과를출력한다. 그리고미세먼지와초미세먼지의합의평균이 115이상이면학교휴교에관련한 SMS 문자를출력한다. 해결방법 1 #include <stdio.h> #include <stdlib.h> int main() freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); int cnt = 0; int pm100, pm25, o3; scanf("%d %d %d", &pm100, &pm25, &o3); if(pm100>=0 && pm100<=30) printf("%d Blue", pm100); if (cnt<1) cnt = 1; else if(pm100>=31 && pm100<=80) printf("%d Green", pm100); if (cnt<2) cnt = 2; else if(pm100>=81 && pm100<=150) printf("%d Yellow", pm100); if (cnt<3) cnt = 3; else if(pm100>=151) printf("%d Red", pm100); if (cnt<4) cnt = 4; - 3 -
printf("\n"); if(pm25>=0 && pm25<=15) printf("%d Blue", pm25); if (cnt<1) cnt = 1; else if(pm25>=16 && pm25<=35) printf("%d Green", pm25); if (cnt<2) cnt = 2; else if(pm25>=36 && pm25<=75) printf("%d Yellow", pm25); if (cnt<3) cnt = 3; else if(pm25>=76) printf("%d Red", pm25); if (cnt<4) cnt = 4; printf("\n"); if(o3>=0 && o3<=30) printf("%d Blue", o3); if (cnt<1) cnt = 1; else if(o3>=31 && o3<=90) printf("%d Green", o3); if (cnt<2) cnt = 2; else if(o3>=91 && o3<=150) printf("%d Yellow", o3); if (cnt<3) cnt = 3; else if(o3>=151) printf("%d Red", o3); if (cnt<4) cnt = 4; - 4 -
printf("\n"); switch(cnt) case 1 : printf("recommend"); break; case 2 : printf("possible"); break; case 3 : printf("careful"); break; case 4 : printf("stop"); break; if((pm100+pm25)/2 >= 115) printf("\nsms"); return 0; - 5 -
해결방법 2 #include <stdio.h> int main(void) FILE *fi = fopen("input.txt", "rt"); FILE *fo = fopen("output.txt", "wt"); //fi = stdin; fo = stdout; int p, m, o; int b, g, y, r; b=g=y=r=0; fscanf(fi, "%d %d %d", &p, &m, &o); // 미세먼지 if(0<=p && p<=30) fprintf(fo, "%d Blue", p); b=1; else if(31<=p && p<=80) fprintf(fo, "%d Green", p); g=1; else if(81<=p && p<=150) fprintf(fo, "%d Yellow", p); y=1; else if(151<=p) fprintf(fo, "%d Red", p); r=1; // 초미세먼지 if(0<=m && m<=15) fprintf(fo, "\n%d Blue", m); b=1; else if(16<=m && m<=35) fprintf(fo, "\n%d Green", m); - 6 -
g=1; else if(36<=m && m<=75) fprintf(fo, "\n%d Yellow", m); y=1; else if(76<=m) fprintf(fo, "\n%d Red", m); r=1; // 오존농도 if(0<=o && o<=30) fprintf(fo, "\n%d Blue", o); b=1; else if(31<=o && o<=90) fprintf(fo, "\n%d Green", o); g=1; else if(91<=o && o<=150) fprintf(fo, "\n%d Yellow", o); y=1; else if(151<=o) fprintf(fo, "\n%d Red", o); r=1; // 야외활동 if (r) fprintf(fo, "\nstop"); else if(y) fprintf(fo, "\ncareful"); else if(g) fprintf(fo, "\npossible"); else if(b) fprintf(fo, "\nrecommend"); // SMS - 7 -
if ( (p+m)/2 >= 115 ) fprintf(fo, "\nsms"); fclose(fi); fclose(fo); return 0; - 8 -
[ 문제3] 숫자야구게임입력된숫자 a( 정답 ) 를둘째행부터입력되는숫자와비교하여입력되는횟수 (n번) 만큼출력하는문제이다. 이때입력되는숫자들은문자열 %s 형태로입력받는방법이있고, 다른방법으로는입력된숫자를세자리정수형태로입력받아백의자리, 십의자리, 일의자리를따로떼어낸후비교하는방법이있다. 예시답안에서는전자의경우를따라문자열로입력받은후배열을비교하여출력한다. 해결방법 1 #include<stdio.h> int main() FILE*in=fopen("input.txt", "r"); FILE*out=fopen("output.txt","w"); int n, i, j, cnt_b=0, cnt_s=0, key=0, flag=0; char a[4], k[4]; fscanf(in, "%s %d", a, &n); for(i=0; i<n; i++) fscanf(in, "%s", k); key=0; cnt_b=0; cnt_s=0; while(key<=2) for(j=0; j<3; j++) if(k[key]==a[j]&&key==j) cnt_s++; // 숫자, 자리위치가모두일치할경우 break; else if(k[key]==a[j]&&key!=j) cnt_b++; // 숫자가일치하고자리위치는일치하지않을경우 - 9 -
key++; if(cnt_b==0&&cnt_s==0) // 일치하는숫자가없을경우 fprintf(out, "OUT\n"); else if(cnt_b==0&&cnt_s>0) fprintf(out, "%ds\n", cnt_s); else if(cnt_b>0&&cnt_s==0) fprintf(out, "%db\n", cnt_b); else if(cnt_b>0&&cnt_s>0) fprintf(out, "%ds%db\n", cnt_s, cnt_b); if(cnt_s==3) fprintf(out, "SUCCESS"); flag=1; //3S를찾아내면 SUCCESS 출력, flag값을변경하여표시 break; if(flag==0) fprintf(out, "FAIL"); // 만약도전횟수내에 3S를찾지못하면 FAIL 출력 fclose(in); fclose(out); return 0; - 10 -
해결방법 2 #include <stdio.h> int main(void) FILE *fi = fopen("input.txt", "rt"); FILE *fo = fopen("output.txt", "wt"); //fi = stdin; fo = stdout; int i, j, k, n; int b, s; char a[4], x[4]; fscanf(fi, "%s %d", a, &n); for (k=0; k<n; k++) b=0; s=0; fscanf(fi, "%s", x); for (i=0; i<=2; i++) for (j=0; j<=2; j++) if(a[i] == x[j]) if(i==j) s++; else b++; if(s==3) fprintf(fo, "3S"); fprintf(fo, "\nsuccess"); return 0; else if(b==0 && s==0) fprintf(fo, "OUT"); else if(s) fprintf(fo, "%ds", s); if(b) fprintf(fo, "%db", b); - 11 -
fprintf(fo, "\n"); fprintf(fo, "FAIL"); fclose(fi); fclose(fo); return 0; - 12 -
[ 문제4] 영어로된문장바꾸기첫번째문자는무조건대문자로바꾸고, 나머지문자는 I 의용법으로쓰일때를제외하고는모두소문자로처리한다. 중간에숫자를영어단어로바꾸는경우에는, 문장의중간에숫자보다길이가더긴문자열을어떻게삽입할것인지에대한고민이필요하다. 다양한방법이있을수있으나, 예시답안에서는변환출력할문자열의배열을따로만들어서조합하는방법을사용했다. 해결방법 1 #include <stdio.h> int main(void) FILE *fi = fopen("input.txt", "rt"); FILE *fo = fopen("output.txt", "wt"); //fi = stdin; fo = stdout; char s[201]; char num[10][6] = "zero","one","two","three","four","five","six","seven","eight","nine"; int i=0; fgets(s, 201, fi); // 띄어쓰기입력받을수있음 // 문장첫글자는대문자 if('a'<=s[i] && s[i]<='z') s[i]=s[i]-('a'-'a'); fprintf(fo, "%c", s[i]); i++; while(s[i]) if('0'<=s[i] && s[i]<='9') fprintf(fo, "%s", num[s[i]-'0']); else if( (s[i] == 'i' s[i] == 'I') &&!( ('A'<=s[i-1] && s[i-1]<='z') ('a'<=s[i-1] && s[i-1]<='z') ) - 13 -
&&!( ('A'<=s[i+1] && s[i+1]<='z') ('a'<=s[i+1] && s[i+1]<='z') ) ) fprintf(fo, "I"); else if('a'<=s[i] && s[i]<='z') fprintf(fo, "%c", s[i]+('a'-'a')); else fprintf(fo, "%c", s[i]); i++; fclose(fi); fclose(fo); return 0; - 14 -
해결방법 2 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); char sentence[200]='\0',; char sentence2[200]='\0',; char *number; int i,j,k,size_sent,size_num; gets(sentence); if(sentence[0]>=97&&sentence[0]<123) sentence2[0]=sentence[0]-32; else sentence2[0]=sentence[0]; size_sent=strlen(sentence); j=1; for(i=1;i<size_sent;i++) if(sentence[i]>=48&&sentence[i]<=57) switch(sentence[i]) case '0': number="zero"; break; case '1': number="one"; break; case '2': number="two"; break; case '3': number="three"; break; case '4': number="four"; break; case '5': number="five"; break; case '6': number="six"; break; case '7': number="seven"; break; case '8': number="eight"; break; - 15 -
case '9': number="nine"; break; default : break; size_num=strlen(number); for(k=0;k<size_num;k++) sentence2[j+k]=number[k]; size_sent=size_sent+size_num-1; j=j+size_num-1; else if(sentence[i]==105&&sentence[i-1]==32&&i<size_sent-1) if(sentence[i+1]==32 sentence[i+1]==33 sentence[i+1]==46 sentence[i+1]==6 3) sentence2[j]=sentence[i]-32; else sentence2[j]=105; else if(sentence[i]==105&&sentence[i-1]==32&&i>=size_sent-1) sentence2[j]=sentence[i]-32; else if(sentence[i]>=65&&sentence[i]<=90) if(sentence[i]==73) if(sentence[i-1]==32&&i<size_sent-1) if(sentence[i+1]==32 sentence[i+1]==33 sentence[i+1]==46 sentence[i+1]==6 3) sentence2[j]=73; else sentence2[j]=105; else sentence2[j]=105; - 16 -
else sentence2[j]=sentence[i]+32; else sentence2[j]=sentence[i]; j++; printf("%s",sentence2); return 0; - 17 -
- 18 -
[ 문제 5] 저항만들기 해결방법 1 이문제는동적계획법으로해결할수있다. 동적계획법 : 문제를크기가작은문제로분할한뒤, 답을구하기위해같은부분문제를몇번이고반복해서해결한다. 이때한번해결한부분문제의해답을배열표에기억해두었다가필요할때에배열표를참조하여시간을절약한다. n=3일때가능한저항체의종류는 1, 3, 5, 9 이다. 먼저부품의저항이가장큰저항체값인 9 일때까지해답을배열표에저장한다. R=1일때최소한의저항체의수는배열 s3[1] 방에는저장 R=2일때최소한의저항체의수는배열 s3[2] 방에는저장... R=9일때최소한의저항체의수는배열 s3[9] 방에는저장 R=10의부품을만들기위해필요한최소한의저항체의수는다음의 1 ~ 4 중에서가장작은방법을선택하는것이다. 1 (10-1) 을만들기위한최소한의저항체수 + 1개 2 (10-3) 을만들기위한최소한의저항체수 + 1개 3 (10-5) 을만들기위한최소한의저항체수 + 1개 4 (10-9) 을만들기위한최소한의저항체수 + 1개 R=i 만들기위한최소한의저항체의수를 s3[i] 는 s3[i]=min(s3[i-1]+1,s3[i-3]+1,s3[i-5]+1,s3[i-9]+1) 점화식 n=6일때가능한저항체의종류는 1, 5, 6, 9 이다. 먼저부품의저항이가장큰저항체값인 9일때까지해답을배열표에저장한다. R=i 만들기위한최소한의저항체의수를 s6[i] 는 s6[i]=min(s6[i-1]+1,s6[i-5]+1,s6[i-6]+1,s6[i-9]+1) 점화식 n=11일때가능한저항체의종류는 1, 5, 9, 11 이다. 먼저부품의저항이가장큰저항체값인 11일때까지해답을배열표에저장한다. R=i 만들기위한최소한의저항체의수를 s1[i] 는 s1[i]=min(s1[i-1]+1,s1[i-5]+1,s1[i-9]+1,s1[i-11]+1) 점화식 여기서함수 min(a,b,c,d) 는 a,b,c,d 값중최솟값을출력하는함수이다. - 19 -
#include<stdio.h> int min(int x,int y,int w,int z) int temp=x; if(temp>y) temp=y; if(temp>w) temp=w; if(temp>z) temp=z; return temp; int main() freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int R; //R은만들려는저항값 int s3[510]; // n=3을추가할때입력을위한배열 int a=1, b=5, c=9; scanf("%d",&r); s3[1]=1; s3[2]=2; s3[3]=1; s3[4]=2; s3[5]=1; s3[6]=2; s3[7]=3; s3[8]=2; s3[9]=1; int i; for(i=10;i<=r;i++) s3[i]=min(s3[i-a]+1,s3[i-3]+1,s3[i-b]+1,s3[i-c]+1); int s6[510]; // n=6을추가할때입력을위한배열 s6[1]=1; s6[2]=2; s6[3]=3; s6[4]=4; - 20 -
s6[5]=1; s6[6]=1; s6[7]=2; s6[8]=3; s6[9]=1; for(i=10;i<=r;i++) s6[i]=min(s6[i-a]+1,s6[i-6]+1,s6[i-b]+1,s6[i-c]+1); int s1[510]; // n=11을추가할때입력을위한배열 s1[1]=1; s1[2]=2; s1[3]=3; s1[4]=4; s1[5]=1; s1[6]=2; s1[7]=3; s1[8]=4; s1[9]=1; s1[10]=2; s1[11]=1; for(i=12;i<=r;i++) s1[i]=min(s1[i-a]+1,s1[i-11]+1,s1[i-b]+1,s1[i-c]+1); printf("%d %d %d",s3[r],s6[r],s1[r]); return 0; - 21 -