席替えのプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
nnn

席替えのプログラム

#1

投稿記事 by nnn » 13年前

席替えのプログラムを作って先生のところへ持っていったら、
「四面楚歌(男子の周りが女子だけにならないように、又女子の周りが男子だけにならないようにすること)
のプログラムを組め。」
とか言ってきたんですよ。

クラスの人数は37で固定してあります。
本当は、どんな人数でも対応したいところですが、
技術も時間も全然たりないので作れませんでした・・・・
プロセスは配列に1~37をぶち込んで、
rand関数で得た2つの番号を入れ替えるだけの
簡単なソースです。

席は前から






3人です。計37


で、その先生に持っていったプログラムがこちら。

コード:

#include<stdio.h>
#include<stdlib.h>

int main()
{
	srand(time(NULL));
	int a[100];
	int b[100];
	int c;
	int d;
	int e;
	int f;
	int g;
	int h;
	int i;
	int j;
	int t,y;
	int yy[50];
	int l,m;
	int o;
	l=0;
	m=0;
	d=1;
	printf("人数");
	scanf("%d",&c);
	o=y;
	e=c;
	f=c;
	m=c;
	c--;
	for(;c>=0;c--)
	{
		a[c]=d;
		d++;
	}
	int p;
	p=9999;
	//for(int p=0;p<f;p++)printf("%d\n",a[p]);
	for(;p>=0;p--)
	{
		printf("%d\n",p);
		g=rand();
		//g=2147483648;
		for(;g>0;g--)
		{
			h=rand()%f;//入れ替え番号
			i=rand()%f;//入れ替え番号
			j=a[h];
			a[h]=a[i];
			a[i]=j;
		}
	}

	f--;
	//以下表示関係
	for(;f>=0;f--)
	{
		printf("%d ",a[f]);
		if(f==31)
		{	printf("\n\n");
		}
		if(f==25)
		{	printf("\n\n");
		}
		if(f==19)
		{	printf("\n\n");
		}
		if(f==13)
		{	printf("\n\n");
		}
		if(f==7)
		{	printf("\n\n   ");
		}
		if(f==3)
		{	printf("\n\n   ");
		}
			
	}
	printf("\n\n");
	
	return 0;
}

どうか四面楚歌対策の作り方やソースを投稿してください。

アバター
バグ
記事: 130
登録日時: 15年前
住所: 愛媛県
連絡を取る:

Re: 席替えのプログラム

#2

投稿記事 by バグ » 13年前

男性と女性の人数は固定?可変?
それから四面楚歌の定義は前後左右に異性しかいない状態ということでよろしいですか?


あと、端っこの四面楚歌はどう考えたらいいですか?

男女男
男男男
こういう状況は女の子にとっては四面楚歌ですか?



男女
女女
こういう状況は男の子にとっては四面楚歌ですか?

non
記事: 1097
登録日時: 14年前

Re: 席替えのプログラム

#3

投稿記事 by non » 13年前

nnn さんが書きました: 席は前から






3人です。計37
机の配置を正確に示してください。
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■

または
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
  ■ ■ ■ ■
  ■ ■ ■
non

アバター
バグ
記事: 130
登録日時: 15年前
住所: 愛媛県
連絡を取る:

Re: 席替えのプログラム

#4

投稿記事 by バグ » 13年前

さっき、私が質問したことを考慮しない場合はこんな感じかな?
ランダムで入れ替えるだけの運任せなアルゴリズムなので、お手本にはならないでしょうけどwww
とりあえず、四面楚歌にならないように席替えしてくれますよ。

コード:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#define YOKO 6
#define TATE 7
#define DANSHI 19
#define JYOSHI 18
#define NINZU 37

// 男女をランダムにシャッフル
void danjyo_shuffle(int* pseki)
{
	for (int i = 1; i < NINZU; ++i)
	{
		int a = rand() % i;
		if (*(pseki + i) == 0)
		{
			continue;
		}
		else if (*(pseki + a) == 0)
		{
			--i;
			continue;
		}
		else
		{
			int b = *(pseki + i);
			*(pseki + i) = *(pseki + a);
			*(pseki + a) = b;		
		}
	}
}

// 四面楚歌判定
int shimensoka_judge(int seki[TATE][YOKO])
{
	int res = 0;
	for (int i = 1; i < TATE - 1; ++i)
	{
		for (int j = 1; j < YOKO - 1; ++j)
		{
			if (seki[i][j] == 0)
			{
				continue;
			}

			int chk = 1;
			int x[] = {-1, 0, 1, 0};
			int y[] = {0, -1, 0, 1};
			for (int k = 0; k < 4; ++k)
			{
				chk &= (seki[i][j] != seki[i + x[k]][j + y[k]]);
			}
			res |= chk;
		}
	}
	return res;
}

// 出席番号シャッフル
void bango_shuffle(int* pbango, int ninzu)
{
	for (int i = 1; i < ninzu; ++i)
	{
		int a = rand() % i;
		int b = *(pbango + i);
		*(pbango + i) = *(pbango + a);
		*(pbango + a) = b;		
	}
}

// 出席番号による席の割り振り
void set_danjyo(int seki[TATE][YOKO], int* pdanshi, int* pjyoshi)
{
	int dcnt = 0;
	int jcnt = 0;
	for (int i = 0; i < TATE; ++i)
	{
		for (int j = 0; j < YOKO; ++j)
		{
			if (seki[i][j] == 0)
			{
				continue;
			}
			else if (seki[i][j] == 1)
			{
				seki[i][j] = pdanshi[dcnt++];
			}
			else
			{
				seki[i][j] = pjyoshi[jcnt++];
			}
		}
	}
}

// 席順の表示処理
void disp_seki(int seki[TATE][YOKO])
{
	for (int i = 0; i < TATE; ++i)
	{
		for (int j = 0; j < YOKO; ++j)
		{
			printf((j != (YOKO - 1)) ? "%02d, " : "%02d\n", seki[i][j]);
		}
	}
	puts("\n");
}

void main(void)
{
	// (0:誰も座っていない場所、1:男子、2:女子)で初期化する
	int seki[TATE][YOKO] =	{
								{1, 1, 1, 1, 1, 1},
								{1, 1, 1, 1, 1, 1},
								{1, 1, 1, 1, 1, 1},
								{1, 2, 2, 2, 2, 2},
								{2, 2, 2, 2, 2, 2},
								{0, 2, 2, 2, 2, 0},
								{0, 2, 2, 2, 0, 0}
							};
	// 出席番号(男子1~19、女子20~37とする)
	int danshi[DANSHI] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
	int jyoshi[JYOSHI] = { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37 };

	srand((unsigned)time(NULL));

	// 男女の割り振りを行う
	int jdg = 1;
	while (jdg)
	{
		danjyo_shuffle(&seki[0][0]);
		jdg = shimensoka_judge(seki);
	}
	
	// 男女だけで割り振った席を表示
	disp_seki(seki);

	// 出席番号シャッフル
	bango_shuffle(danshi, DANSHI);
	bango_shuffle(jyoshi, JYOSHI);

	// 出席番号による男女別での席の割り振り
	set_danjyo(seki, danshi, jyoshi);

	// 最終的な席順の表示
	disp_seki(seki);

	int a = 0;
	scanf("%d", &a);
}

nnn

Re: 席替えのプログラム

#5

投稿記事 by nnn » 13年前

パソコンが故障寸前で返信が遅れました。すいません。
今更ですが返信しておきます。

席は前から
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
  ■ ■ ■ ■
  ■ ■ ■
です。


四面楚歌についてももう少し詳しく説明します。

↓まずはバグさんの質問から↓

男女男
男男男

男女
女女

これら共に四面楚歌です。

男男男  女女女
男女男  女男女
男男男  女女女

これを四面楚歌の定義としています。

non
記事: 1097
登録日時: 14年前

Re: 席替えのプログラム

#6

投稿記事 by non » 13年前

基本的な考え方はバグさんのがよいと思います。ただ、バグさんも仰っているように、端の席は見ていないようなので、
配列を、もう一回り大きく確保するとよいでしょう。
int seki[TATE+2][YOKO+2]にして、外の周りは0で初期化しておきます。
non

box
記事: 2002
登録日時: 14年前

Re: 席替えのプログラム

#7

投稿記事 by box » 13年前

男子・女子の人数が固定なのか可変なのか、という質問が出ていたように思います。
これに対する回答は、どのようになっているでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

nnn

Re: 席替えのプログラム

#8

投稿記事 by nnn » 13年前

男女の人数は可変でも固定でも構いません。

non
記事: 1097
登録日時: 14年前

Re: 席替えのプログラム

#9

投稿記事 by non » 13年前

解決ですか?
それなら、参考までに完成したプログラムを載せてください。
もっと、アドバイスできることがあるかも知れませんし、初学者の参考になります。
non

nnn

Re: 席替えのプログラム

#10

投稿記事 by nnn » 13年前

↓nonさんの要望通り、プログラム載せておきます。↓

コード:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>


 
#define YOKO 8
#define TATE 9
#define DANSHI 23
#define JYOSHI 14
#define NINZU 37

// 男女をランダムにシャッフル
void danjyo_shuffle(int* pseki)
{
    for (int i = 1; i < TATE*YOKO; i++)
    {
        int a = rand() % NINZU;
        if (*(pseki + i) == 0)
        {
            continue;
        }
		else if (*(pseki + a) == 0)
        {
            --i;
            continue;
        }
        else
        {
            int b = *(pseki + i);
            *(pseki + i) = *(pseki + a);
            *(pseki + a) = b;       
        }
        
    }
}
 
// 四面楚歌判定
int shimensoka_judge(int seki[TATE][YOKO])
{
    int res = 0;
    for (int i = 1; i < TATE - 1; ++i)
    {
        for (int j = 1; j < YOKO - 1; ++j)
        {
            if (seki[i][j] == 0)
            {
                continue;
            }
 
            int chk = 1;
            int x[] = {-1, 0, 1, 0};
            int y[] = {0, -1, 0, 1};
            for (int k = 0; k < 4; k++)
            {
                chk &= (seki[i][j] != seki[i + x[k]][j + y[k]]);
            }
            res |= chk;
        }
    }
    return res;
}
 
// 出席番号シャッフル
void bango_shuffle(int* pbango, int ninzu)
{
    for (int i = 1; i < ninzu; ++i)
    {
        int a = rand() % i;
        int b = *(pbango + i);
        *(pbango + i) = *(pbango + a);
        *(pbango + a) = b;      
    }
}
 
// 出席番号による席の割り振り
void set_danjyo(int seki[TATE][YOKO], int* pdanshi, int* pjyoshi)
{
    int dcnt = 0;
    int jcnt = 0;
    for (int i = 0; i < TATE; ++i)
    {
        for (int j = 0; j < YOKO; ++j)
        {
            if (seki[i][j] == 0)
            {
                continue;
            }
            else if (seki[i][j] == 1)
            {
                seki[i][j] = pdanshi[dcnt++];
            }
            else
            {
                seki[i][j] = pjyoshi[jcnt++];
            }
        }
    }
}
 
// 席順の表示処理
void disp_seki(int seki[TATE][YOKO])
{
    for (int i = 0; i < TATE; i++)
    {
        for (int j = 0; j < YOKO; j++)
        {
            printf((j != (YOKO - 1)) ? "%02d, " : "%02d\n", seki[i][j]);
        }
    }
    puts("\n");
}
 
void main(void)
{
    // (0:誰も座っていない場所、1:男子、2:女子)で初期化する
    int SEKI[TATE][YOKO] =  {
								{0, 0, 0, 0, 0, 0, 0, 0},
                                {0, 1, 1, 1, 1, 1, 1, 0},
                                {0, 1, 1, 1, 1, 1, 1, 0},
                                {0, 1, 1, 1, 1, 1, 1, 0},
                                {0, 1, 1, 1, 1, 1, 2, 0},
                                {0, 2, 2, 2, 2, 2, 2, 0},
                                {0, 0, 2, 2, 2, 2, 0, 0},
                                {0, 0, 2, 2, 2, 0, 0, 0},
								{0, 0, 0, 0, 0, 0, 0, 0}
                            };
	int seki[TATE][YOKO] =  {
								{0, 0, 0, 0, 0, 0, 0, 0},
                                {0, 1, 1, 1, 1, 1, 1, 0},
                                {0, 1, 1, 1, 1, 1, 1, 0},
                                {0, 1, 1, 1, 1, 1, 1, 0},
                                {0, 1, 1, 1, 1, 1, 2, 0},
                                {0, 2, 2, 2, 2, 2, 2, 0},
                                {0, 0, 2, 2, 2, 2, 0, 0},
                                {0, 0, 2, 2, 2, 0, 0, 0},
								{0, 0, 0, 0, 0, 0, 0, 0}
                            };
    // 出席番号(男子1~19、女子20~37とする)
    int danshi[DANSHI] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
    int jyoshi[JYOSHI] = { 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37 };
 
    srand((unsigned)time(NULL));
 
    // 男女の割り振りを行う
	int count;
	count=0;
    int jdg = 1;
    while (jdg)
    {
		for(int i=0;i<TATE;i++){
			for(int j=0;j<YOKO;j++){
				seki[i][j]=SEKI[i][j];
			}
		}
		danjyo_shuffle(&seki[0][0]);
        jdg = shimensoka_judge(seki);count++;
		
    }
    printf("%d\n",count);
    // 男女だけで割り振った席を表示
    disp_seki(seki);
 
    // 出席番号シャッフル
    bango_shuffle(danshi, DANSHI);
    bango_shuffle(jyoshi, JYOSHI);
 
    // 出席番号による男女別での席の割り振り
    set_danjyo(seki, danshi, jyoshi);
 
    // 最終的な席順の表示
    disp_seki(seki);
 
}

閉鎖

“C言語何でも質問掲示板” へ戻る