//配属問題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;
 
                            }              
                            //BをB[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;
                            }              
                            //BをB[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;
                            }              
                            //BをB[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;                
              }
 
              //150*150の配列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「ゼミランキング」〜学生のゼミに対する順位付け
 
              //0〜34番
              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;
                            }              
                            //AをA[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;
                            }
              }
              //35〜69番
              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;
                            }              
                            //AをA[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;
                            }
              }
              //70〜104番
              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;
                            }              
                            //AをA[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;
              }
              //105〜149番(ダミー学生)
              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;
}