//配属問題1「現在の配属方法のシミュレーション」

// 配属問題の部分プログラムNo4「学生ランキング」〜ゼミの学生に対する順位付け

 

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define Znum 15

#define Snum 150

#define N 1000

struct student

{

              int studentnum;

              int Srandnum;

};

struct zemi

{

              int zeminum;

              int randnum;

};

 

int main()

{

              struct student B[Snum],tempB;

              struct zemi A[Znum] , tempA;  

              int ZR[Znum][Snum],SR[Snum][Znum];

              int D[Snum][Snum],H[Snum][Snum];   

              int i,j,n,r,c,x;

              int Slist[Snum],Zlist[5];

             int RH[Snum][Snum],RD[Snum][Snum];

    int P[Snum],SAI[Snum],HDi[Snum];

              int onoff;

              for(i=0;i<Snum;i++)  Slist[i]=0;

              for(i=0;i<5;i++)  Zlist[i]=0;

for(x=0;x<N;x++)

{

              for(i=0;i<Snum;i++)              {P[i]=Snum;SAI[i]=0;HDi[i]=0;}

              for(i=0;i<Snum;i++)

              {

                            for(j=0;j<Snum;j++)              {RH[i][j]=0;RD[i][j]=0;}

              }

              //分野1

  

              for (i=0;i<5;i++)

              {

                            for (j=0;j<Snum;j++)

                            {                           

                                          B[j].studentnum = j;

                                          if(j<35)       B[j].Srandnum = rand()%200;

                                          else if(j<70) B[j].Srandnum = rand()%200;

                                          else if(j<105) B[j].Srandnum = rand()%50;

                                          else  B[j].Srandnum = 0;

 

                            }             

                            //BB[j].Srandnumについて大きい順に並べ替え

                            for(j=0;j<Snum-1;j++)

                            {

                                          for(n=j+1;n<Snum;n++)

                                          {             

                                                        if(B[j].Srandnum < B[n].Srandnum)         

                                                        {tempB=B[n];B[n]=B[j];B[j]=tempB;}

                                          }

                            }

                                          //配列ZRを出力

            for(n=0;n<Snum;n++)              ZR[i][n]=B[n].studentnum;

                           

              }

              //分野2

              for (i=5;i<10;i++)

              {

                            for (j=0;j<Snum;j++)

                            {                           

                                          B[j].studentnum = j;

                                          if(j<35)       B[j].Srandnum = rand()%100;

                                          else if(j<70)  B[j].Srandnum = rand()%200;

                                          else if(j<105) B[j].Srandnum = rand()%100;

                                          else  B[j].Srandnum = 0;

                            }             

                            //BB[j].Srandnumについて大きい順に並べ替え

                            for(j=0;j<Snum-1;j++)

                            {

                                          for(n=j+1;n<Snum;n++)

                                          {             

                                                        if(B[j].Srandnum < B[n].Srandnum)         

                                                        {tempB=B[n];B[n]=B[j];B[j]=tempB;}

                                          }

                            }

                                          //配列ZRを出力

            for(n=0;n<Snum;n++)              ZR[i][n]=B[n].studentnum;               

              }

              //分野3

              for (i=10;i<Znum;i++)

              {

                            for (j=0;j<Snum;j++)

                            {                           

                                          B[j].studentnum = j;

                                          if(j<35)       B[j].Srandnum = rand()%100;

                                          else if(j<70)  B[j].Srandnum = rand()%100;

                                          else if(j<105) B[j].Srandnum = rand()%200;

                                          else  B[j].Srandnum = 0;

                            }             

                            //BB[j].Srandnumについて大きい順に並べ替え

                            for(j=0;j<Snum-1;j++)

                            {

                                          for(n=j+1;n<Snum;n++)

                                          {             

                                                        if(B[j].Srandnum < B[n].Srandnum)         

                                                        {tempB=B[n];B[n]=B[j];B[j]=tempB;}

                                          }

                            }

                                          //配列ZRを出力

            for(n=0;n<Snum;n++)

                                                        ZR[i][n]=B[n].studentnum;               

              }

 

              //150150の配列Dに拡張

              for(j=0;j<Znum;j++)

              {

                            for(i=0;i<Snum;i++)

                            {             

                                          for(n=j*10;n<j*10+10;n++)              D[n][i] = ZR[j][i];                                         

                            }                           

              }

 

//配属問題部分プログラムNo3「ゼミランキング」〜学生のゼミに対する順位付け

 

              //034

              for (i=0;i<35;i++)

              {

                            for (j=0;j<Znum;j++)

                            {                                         

                                          A[j].zeminum = j;

                                          if(j<5)       A[j].randnum = rand()%100;

                                          else if(j<10) A[j].randnum = rand()%100;

                                          else          A[j].randnum = rand()%100;

                            }             

                            //AA[j]->randnumについて大きい順に並べ替え

                            for(j=0;j<Znum-1;j++)

                            {

                                          for(n=j+1;n<Znum;n++)

                                          {             

                                                        if(A[j].randnum < A[n].randnum)            

                                                        {tempA=A[n];A[n]=A[j];A[j]=tempA;}

                                          }

                                          //配列SRを出力

            for(n=0;n<Znum;n++)              SR[i][n]=A[n].zeminum;

                            }

              }

              //3569

              for (i=35;i<70;i++)

              {

                            for (j=0;j<Znum;j++)

                            {                                         

                                          A[j].zeminum = j;

                                          if (j<5)      A[j].randnum = rand()%100;

                                          else if(j<10)  A[j].randnum = rand()%100;

                                          else          A[j].randnum = rand()%100;

                            }             

                            //AA[j]->randnumについて大きい順に並べ替え

                            for(j=0;j<Znum-1;j++)

                            {

                                          for(n=j+1;n<Znum;n++)

                                          {             

                                                        if(A[j].randnum < A[n].randnum)            

                                                        {tempA=A[n];A[n]=A[j];A[j]=tempA;}

                                          }

                                          //配列SRを出力

            for(n=0;n<Znum;n++)              SR[i][n]=A[n].zeminum;

                            }

              }

              //70104

              for (i=70;i<105;i++)

              {

                            for (j=0;j<Znum;j++)

                            {                                         

                                          A[j].zeminum = j;

                                          if(j<5)                              A[j].randnum = rand()%100;

                                          else if(j<10) A[j].randnum = rand()%100;

                                          else          A[j].randnum = rand()%100;

                            }             

                            //AA[j]->randnumについて大きい順に並べ替え

                            for(j=0;j<Znum-1;j++)

                            {

                                          for(n=j+1;n<Znum;n++)

                                          {             

                                                        if(A[j].randnum < A[n].randnum)            

                                                        {tempA=A[n];A[n]=A[j];A[j]=tempA;}

                                          }

                            }

                                          //配列SRを出力

            for(n=0;n<Znum;n++)              SR[i][n]=A[n].zeminum;

              }

              //105149番(ダミー学生)

              for (i=105;i<Snum;i++)

              {

                            for (j=0;j<Znum;j++)

                            {                                         

                                          A[j].zeminum = j;

                                          A[j].randnum = 100;

                            }                                         

                            //配列SRを出力

         for(n=0;n<Znum;n++)              SR[i][n]=A[n].zeminum;

              }

              //150*150の配列Hに拡張する

              for(i=0;i<Snum;i++)

              {

                            for(j=0;j<Znum;j++)

                            {

              //定員は10人とする

                                          r = 0;

                                          for(n=j*10;n<j*10+10;n++)

                                          {

                                                        H[i][n]=SR[i][j]*10+r;

                                                        r=r+1;

                                          }

                            }

              }

//配属問題部分プログラムNo1「現在の配属方法」〜現在の配属方法のアルゴリズム

/*配列RH->学生はそのゼミを何番目に好きかを表す配列

               RD->ゼミはその学生を何番目に好きかを表す配列*/             

             

     for (i=0;i<Snum;i++)

               {

                             for (j=0;j<Snum;j++)

                             {

                                           RD[i][D[i][j]] = j;

                             }

               }

              for (i=0;i<Snum;i++)

              {

                            for (j=0;j<Snum;j++)

                            {

                                          RH[i][H[i][j]] = j;

                            }

              }

 

/*現在の配属方法*/

/*学生の希望提出過程*/

              for (n=0;n<Snum;n++)

              {

/*希望調整の処理*/

                            for (c=0;c<Snum;c++)

                            {

                                          onoff = 1;

                                          /*男性(c)は所属してるか*/   

                                          if (HDi[c]==1) onoff = 0;                                         

                                          while(onoff==1)

                                          {

                                                        /*希望ゼミは空いているか*/

                                                        if(P[H[c][n+SAI[c]]]==Snum)              onoff = 0;

                                                        else              SAI[c]=SAI[c]+1;                                                                                                 

                                          }                                         

                            }             

/*仮配属*/             

                            for (c=0;c<Snum;c++){

                                          if (HDi[c] == 1){

                                          }

                                          else{

                                              if (P[H[c][n+SAI[c]]] > RD[H[c][n+SAI[c]]][c]){

                                                            P[H[c][n+SAI[c]]] = RD[H[c][n+SAI[c]]][c];

                                                        }

                                          }

                            }

/*実配属*/

                            for (c=0;c<Snum;c++){

                                          if(P[c]==Snum){

                                                       

                                          }

                                          else{

                                                        if (HDi[D[c][P[c]]]==1){

                                                        }

                                                        else{

                                                                      HDi[D[c][P[c]]]=1;

                                                        }

                                          }

                            }

              }

 

//学生はゼミ(ペア)を何番目に好きか?の統計

              for(i=0;i<Snum;i++)

              {

                            if(D[i][P[i]]<105)

                                           Slist[RH[D[i][P[i]]][i]] = Slist[RH[D[i][P[i]]][i]] +1;

              }

//ゼミはどのくらい好ましい学生を得たかの統計

              for(i=0;i<Snum;i++)

              {

                            if(D[i][P[i]]<105)

                            {

                                          if(RH[D[i][P[i]]][i]<21) Zlist[0]= Zlist[0] +1;

                                          else if(RH[D[i][P[i]]][i]<42) Zlist[1] = Zlist[1]+1;

                                          else if(RH[D[i][P[i]]][i]<63) Zlist[2] = Zlist[2]+1;

                                          else if(RH[D[i][P[i]]][i]<84) Zlist[3] = Zlist[3]+1;

                                          else Zlist[4]=Zlist[4]+1;                     

                            }

              }

}

              //ゼミを一つのイメージにする

              for(i=0;i<Znum;i++)

              {

                            n=0;

                            for(j=i*10;j<i*10+10;j++)   n = n + Slist[j];

                            printf("%d希望の総数は%d\n,",i+1,n);

              }

              for(i=0;i<5;i++) printf("ランク%dの学生数->%d\n",i+1,Zlist[i]);

              return 0;

}