我的网站http;//tigerion.cn
这周有点忙,零散的时间只是想了一些不成熟的东西,但也班门弄斧,拿出来跟大家交流,嘿嘿,不要介意。
第一个问题,我的出发点是这样的:
数组中的元素,由它的下标的关系,而形成一种天然的逻辑关联,或是顺序吧,这点性质很好用。
举几个简单的例子
1 给出一堆数(无重复),范围是1~100,要求将数按顺序输出
那么就可以建立一da[101]的数组,每个元素赋初值为零,然后将每一个数n ,da[n]=1,再按顺序输出即可
本来是杂乱无章的数,由数组下标建立 一种映射之后就变得有序,当然这种方法很局限,这里只是转转思路罢了。
2 做一个发牌的程序。
将每一个牌编号得到1~54号,对于四种花色的 牌1~52,可以按照%4的结果来区分花色,对于分牌也很简单了。
模拟现实生活中分牌的过程,先洗牌,牌洗好后也分好了。因为n%m=1是第一个人的牌,余数为二为第二个人的牌.....
实现过程可以找一个大小为54的容器,da[54],然后随机给每一个位置找一个没用过的牌,
牌分好后再按顺序发给每一个人就行了,若共m个人
第一个人1,1+m,1+2m....
第二个 2,2+m,2+2m...
....
程序写出来吧
//给三个人发牌的程序
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <dos.h>
int main()
{
int loc[54],flag[54],i;//54个位置,54个牌状态的标记
int person[3][18];
char colr[4]={3,4,5,6};//花色
char sig[]={'3','4','5','6','7','8','9','0','J','Q','K','A','2'};
for( i=0;i<54;i++) loc[i]=0,flag[i]=0;//初始化
i=0;
srand(time(NULL));
int temp;
while(i<54) //洗牌
{
temp=rand()%54;
while(flag[temp]) temp=rand()%54;
flag[temp]=1;
loc[i++]=temp;
}
int j=0,key;
for(i=0;i<54;i++) //发牌,顺便排序
{
temp=j;
key=i%3;
while(temp>0&&loc[i]<person[key][temp-1]) person[key][temp]=person[key][temp-1],temp--;
person[key][temp]=loc[i];
if (i&&i%3==2) j++;
}
int card=0;
for(i=0;i<3;i++) //输出
{
cout<<endl<<endl;
for( j=0;j<18;j++)
{
card=person[i][j];
if (card==52) {cout<<" "<<'w';continue;}
if (card==53) {cout<<" "<<'W';continue;}
if (card/4==7) {cout<<" "<<colr[card%4]<<10;continue;}
cout<<" "<<colr[card%4]<<sig[card/4];
}
}
getch();
return 1;
}
3 约瑟夫环问题
问题再描述一下吧,有m个人围成一圈,从1开始轮着数数,数到n的人退出 ,问最后剩的人是谁
从彼此关联的一组数中,“退出”某些位置的数,当然用链表来做比较简单了
然而这个问题用一个一维数组也能巧妙地解决
本质还是链表思想,不过是由一维数组构成的链表
给下标赋予双重含意,嘿嘿,
1 链表中元素的值- 编号,
2 链表中的逻辑地址
那指针呢?我把它变成数组元素的值
例如 a[2]=5就表示第二个人指向(下一个)是第5个
代码如下
#include <iostream>
#define MAX 100
using namespace std;
int main()
{
int cir[MAX],m,n;
cout<<"Please input n m:";
cin>>n>>m;
if (n<1||n>100||m<2)return 0;
for(int i=0;i<n;i++)cir[i]=(i+1)%n;//初始化链表
int s=n,cur=0,count=0;
while(s>1)
{
count=1;
while(count<m-1) cur=cir[cur],count++;//找到出队的上一个结点
cur=cir[cur]=cir[cir[cur]]; //结点出队,cur指向从1开始数的结点
s--;
}
cout<<"最后一个人的编号是:"<<cur+1;
return 1;
}
//gcc编译
二,我偶然间有个想法,能否让由指针构建的链表也像数组一样有种下标的顺序关系,可以方便的访问,
也不用再next,next 麻烦地查找?
方法是有地,嘿嘿,只要愿意想。
有一个现成的链表,由头指针head指向,
我的办法是建立 一个指针数组,*p[n];
然后,p[0]=head,p[i]=p[i-1]->next即可
然而它倒底有什么用处呢,我还没找到好的例子,或许也派不上大的用场,同上面一样,转转思路罢了。
只是想到了一个简单的例子。
做一个RPG游戏,每一个人物构建 一个对象,比方说从今天零晨1点开始,服务器将陆陆续续上线的人建立一个链表,
然后到五点开始分配任务,从五点开始,位置排序成斐波那数列的去挖矿去,其它人去群怪,这时候建立一个临时的指针
数组,与链表搭建关联,便很容易向玩家发布指令了。
然而还是很有局限性,只能算是小聪明罢了。
希望跟 大家多提提意见,多多交流!
我的网站http://tigerion.cn
这周有点忙,零散的时间只是想了一些不成熟的东西,但也班门弄斧,拿出来跟大家交流,嘿嘿,不要介意。
第一个问题,我的出发点是这样的:
数组中的元素,由它的下标的关系,而形成一种天然的逻辑关联,或是顺序吧,这点性质很好用。
举几个简单的例子
1 给出一堆数(无重复),范围是1~100,要求将数按顺序输出
那么就可以建立一da[101]的数组,每个元素赋初值为零,然后将每一个数n ,da[n]=1,再按顺序输出即可
本来是杂乱无章的数,由数组下标建立 一种映射之后就变得有序,当然这种方法很局限,这里只是转转思路罢了。
2 做一个发牌的程序。
将每一个牌编号得到1~54号,对于四种花色的 牌1~52,可以按照%4的结果来区分花色,对于分牌也很简单了。
模拟现实生活中分牌的过程,先洗牌,牌洗好后也分好了。因为n%m=1是第一个人的牌,余数为二为第二个人的牌.....
实现过程可以找一个大小为54的容器,da[54],然后随机给每一个位置找一个没用过的牌,
牌分好后再按顺序发给每一个人就行了,若共m个人
第一个人1,1+m,1+2m....
第二个 2,2+m,2+2m...
....
程序写出来吧
//给三个人发牌的程序
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <dos.h>
int main()
{
int loc[54],flag[54],i;//54个位置,54个牌状态的标记
int person[3][18];
char colr[4]={3,4,5,6};//花色
char sig[]={'3','4','5','6','7','8','9','0','J','Q','K','A','2'};
for( i=0;i<54;i++) loc[i]=0,flag[i]=0;//初始化
i=0;
srand(time(NULL));
int temp;
while(i<54) //洗牌
{
temp=rand()%54;
while(flag[temp]) temp=rand()%54;
flag[temp]=1;
loc[i++]=temp;
}
int j=0,key;
for(i=0;i<54;i++) //发牌,顺便排序
{
temp=j;
key=i%3;
while(temp>0&&loc[i]<person[key][temp-1]) person[key][temp]=person[key][temp-1],temp--;
person[key][temp]=loc[i];
if (i&&i%3==2) j++;
}
int card=0;
for(i=0;i<3;i++) //输出
{
cout<<endl<<endl;
for( j=0;j<18;j++)
{
card=person[i][j];
if (card==52) {cout<<" "<<'w';continue;}
if (card==53) {cout<<" "<<'W';continue;}
if (card/4==7) {cout<<" "<<colr[card%4]<<10;continue;}
cout<<" "<<colr[card%4]<<sig[card/4];
}
}
getch();
return 1;
}
3 约瑟夫环问题
问题再描述一下吧,有m个人围成一圈,从1开始轮着数数,数到n的人退出 ,问最后剩的人是谁
从彼此关联的一组数中,“退出”某些位置的数,当然用链表来做比较简单了
然而这个问题用一个一维数组也能巧妙地解决
本质还是链表思想,不过是由一维数组构成的链表
给下标赋予双重含意,嘿嘿,
1 链表中元素的值- 编号,
2 链表中的逻辑地址
那指针呢?我把它变成数组元素的值
例如 a[2]=5就表示第二个人指向(下一个)是第5个
代码如下
#include <iostream>
#define MAX 100
using namespace std;
int main()
{
int cir[MAX],m,n;
cout<<"Please input n m:";
cin>>n>>m;
if (n<1||n>100||m<2)return 0;
for(int i=0;i<n;i++)cir[i]=(i+1)%n;//初始化链表
int s=n,cur=0,count=0;
while(s>1)
{
count=1;
while(count<m-1) cur=cir[cur],count++;//找到出队的上一个结点
cur=cir[cur]=cir[cir[cur]]; //结点出队,cur指向从1开始数的结点
s--;
}
cout<<"最后一个人的编号是:"<<cur+1;
return 1;
}
//gcc编译
二,我偶然间有个想法,能否让由指针构建的链表也像数组一样有种下标的顺序关系,可以方便的访问,
也不用再next,next 麻烦地查找?
方法是有地,嘿嘿,只要愿意想。
有一个现成的链表,由头指针head指向,
我的办法是建立 一个指针数组,*p[n];
然后,p[0]=head,p[i]=p[i-1]->next即可
然而它倒底有什么用处呢,我还没找到好的例子,或许也派不上大的用场,同上面一样,转转思路罢了。
只是想到了一个简单的例子。
做一个RPG游戏,每一个人物构建 一个对象,比方说从今天零晨1点开始,服务器将陆陆续续上线的人建立一个链表,
然后到五点开始分配任务,从五点开始,位置排序成斐波那数列的去挖矿去,其它人去群怪,这时候建立一个临时的指针
数组,与链表搭建关联,便很容易向玩家发布指令了。
然而还是很有局限性,只能算是小聪明罢了。
希望跟 大家多提提意见,多多交流!
我的网站http://tigerion.cn