테스트 케이스 다 맞고
제가 추가로 10개는 넘게 만들어서 테스트 한 것도 모두 맞았는데
오답이라고 자꾸 결과가 나옵니다.
다른 라이브러리를 안쓰려고 하다보니,
그리고 깔끔하게 짜는 능력이 모자라서
코드가 길고 지저분해서 봐주실 수 있을지 모르겠습니다만
혹시 가능하시다면 조언 부탁드립니다.
우선 순위 큐를 이용해서
먹을 수 있는 음식 수가 가장 적은 사람부터 생각했습니다.
그 사람이 먹을 수 있는 음식 중에
가장 많은 사람이 먹을 수 있는 음식을 택하는 식입니다.
#include<stdio.h>typedefstructPerson{charname[11];intfoods[51];intnum_foods=0;boolavail=false;}PERSON;PERSONP[100];intend=0;voidswap(PERSON*a,PERSON*b){PERSONtmp;tmp=*a;*a=*b;*b=tmp;}voidadd(PERSONn){end++;P[end]=n;intidx=end;intparent=idx/2;while(idx>1){if(P[parent].num_foods>P[idx].num_foods){swap(&P[parent],&P[idx]);idx=parent;parent=idx/2;}elsebreak;}}PERSONpop(){PERSONret=P[1];P[1]=P[end];end--;intidx=1;intchild=2;while(child<=end){if(P[child].num_foods>P[child+1].num_foods)child++;if(P[idx].num_foods>P[child].num_foods){swap(&P[idx],&P[child]);idx=child;child=child*2;}elsebreak;}returnret;}intstrcmp(char*a,char*b){intflag=0;while(*a){if(*(a++)!=*(b++))return-1;}if(*a!=*b)return-1;return1;}voidstrcpy(char*a,char*b){while(*b){*(a++)=*(b++);}*a='\0';}intmain(){intT;intn,m;charfriends[100][11];charfoods[100][100][11];intnum_foods[100];// i번째 음식을 먹을 수 있는 사람 수intFOODS[100]={0,};// i번째 음식이 선택 되었는가(1) 안되었는가(0)inttotal=0;// 먹을 음식이 있는 사람의 수inttotal_foods=0;// 선택한 음식의 수PERSONp[100];scanf("%d",&T);while(T--){scanf("%d %d",&n,&m);for(inti=1;i<=n;i++){scanf("%s",&friends[i]);strcpy(p[i].name,friends[i]);p[i].avail=false;p[i].num_foods=0;}for(inti=1;i<=m;i++){scanf("%d",&num_foods[i]);for(intj=1;j<=num_foods[i];j++){scanf("%s",&foods[i][j]);for(intk=1;k<=n;k++){if(strcmp(p[k].name,foods[i][j])==1)p[k].foods[++p[k].num_foods]=i;}}FOODS[i]=0;}// 우선 순위 큐에 넣음for(inti=1;i<=n;i++)add(p[i]);PERSONselect;for(inti=1;i<=n;i++){select=pop();//먹을 수 있는 음식 수가 가장 적은 사람 if(select.avail==false){select.avail=true;total++;//먹을 음식이 있는 사람 수}elsecontinue;//select food -> select가 먹는 음식들 중 사람들이 많이 먹을 수 있는 음식 선택하기intmax=0;intidx=-1;for(intj=1;j<=select.num_foods;j++){if(FOODS[select.foods[j]]==0)// 아직 선택이 안된 음식{//select.food[j] -> select가 먹을 수 있는 음식들 중 j번째 음식을 먹는 사람 수if(max<num_foods[select.foods[j]]){max=num_foods[select.foods[j]];idx=select.foods[j];}}}FOODS[idx]=1;// idx 음식은 선택됨total_foods++;// 선택된 음식 수//select가 먹을 음식(idx)을 선택했으니까, 얘가 먹는 음식들, 그 음식들을 먹는 사람 수 1씩 감소. for(intj=1;j<=select.num_foods;j++){num_foods[select.foods[j]]--;}//위 음식을 택함으로 자동적으로 먹을 음식이 생긴 사람들. idx 번째 음식을 먹는 사람들.for(intj=1;j<=end;j++){if(P[j].avail==true)continue;//이미 선택된 사람들 넘어가고for(intk=1;k<=P[j].num_foods;k++)// P[j]가 먹는 음식들{if(P[j].foods[k]==idx)// 그 중에 아까 선택한 음식이 있다{P[j].avail=true;// 그러면 P[j]는 선택total++;//먹을 음식이 있는 사람 수 증가//음식을 먹을 수 있는 사람 수 조정 - 선택된 사람들 빼기for(intl=1;l<=P[j].num_foods;l++)// P[j]를 선택하면, P[j]가 먹는 음식들 걔네들을 먹는 사람 수 감소. P[j]를 아예 배제하기 위해{num_foods[P[j].foods[l]]--;}break;}}}if(total==n)break;}printf("%d\n",total_foods);//initializingtotal=0;total_foods=0;end=0;}return0;}
freestar
ALLERGY 문제를 푸는 중입니다.
테스트 케이스 다 맞고
제가 추가로 10개는 넘게 만들어서 테스트 한 것도 모두 맞았는데
오답이라고 자꾸 결과가 나옵니다.
다른 라이브러리를 안쓰려고 하다보니,
그리고 깔끔하게 짜는 능력이 모자라서
코드가 길고 지저분해서 봐주실 수 있을지 모르겠습니다만
혹시 가능하시다면 조언 부탁드립니다.
우선 순위 큐를 이용해서
먹을 수 있는 음식 수가 가장 적은 사람부터 생각했습니다.
그 사람이 먹을 수 있는 음식 중에
가장 많은 사람이 먹을 수 있는 음식을 택하는 식입니다.
9년 전