程序设计思路:
一、小朋友和苹果都具有多样属性(比如高度、编号、状态等,还可以扩展出姓名,重量等)。所以小朋友和苹果要定义成结构体。
二、人和苹果数量都是手动输入,因此数组大小不确定,要使用动态数组(不使用动态,就得得限制用户输入的大小)。
三、题目要求确保摘到的总数最多,从最矮的小朋友开始摘,因此小朋友的数组要进行排序。
四、递归函数实现摘苹果逻辑,每人在自己够到的范围中随机摘两个(不够就拿1个)。(递归函数每次发现一个可摘取的苹果,有50%概率看中,都没看中,默认摘取最后一个看中的苹果)。
下面是代码(控制台刷新函数中cls仅限window系统运行,其它操作系统,删除或修改):
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<malloc.h>
#define AFR 7//苹果图像的行数
#define AFC 6//苹果图像的行数
#define CFR 5//小朋友图像的行数
#define CFC 6//小朋友图像的行数
typedef struct apple//表示苹果数据的结构体
{
int aid;//苹果编号
int height;//苹果的高度
int status;//0:表示未被摘取。1:表示已被摘取
char aframe[AFR][AFC];//表示苹果的图像
}APPE;
typedef struct childern//表示小孩子的编号
{
int cid;//小孩子的编号
int height;//小孩子的身高
int n;//小孩摘取的苹果数量
char cframe[CFR][CFC];//表示小朋友的图像
APPE **appes;//小孩摘取的苹果结构指针数组
}CHN;
int n,m;//苹果和小朋友的个数,设为全局变量
APPE *setApps();//设置苹果。成功返回结构数组,失败返回NULL
CHN *setChns();//设置小盆友。同上。
int orderChnByHeight(CHN *chns);//对小朋友数组按照身高升序排列
int getApple(APPE *appes,CHN *chns,char (*strInfo)[100]);//递归,模拟小朋友依次选苹果。异常返回-1
int showFrame(APPE *appes,CHN *chns,char (*strInfo)[100]);
int main()
{
int i;
char (*strInfo)[100]=NULL;//用于显示操作流水
APPE *appes=NULL;
CHN *chns=NULL;
appes=setApps();
chns=setChns();
if(orderChnByHeight(chns)==-1)return 1;
srand(time(NULL));
strInfo=(char (*)[100])malloc(sizeof(char *)*m*100);
for(i=0;i<m;i++)strInfo[i][0]=0;
if(!strInfo) return 1;
showFrame(appes,chns,strInfo);
return 0;
}
int showFrame(APPE *appes,CHN *chns,char (*strInfo)[100])
{
static int k=1;
int i,j;
system("cls");
printf("\n=============每组图像靠上的数值为高度,靠下的数值为编号============\n");
printf("\n=============为确保能拿到最多的苹果,小朋友们按升序排列============\n");
for(i=0;i<AFR;printf("\n"),i++)
for(j=0;j<n;j++)
printf("%s ",appes[j].aframe[i]);
printf("\n");
for(i=0;i<CFR;printf("\n"),i++)
for(j=0;j<m;j++)
printf("%s ",chns[j].cframe[i]);
printf("\n====================================================================\n");
printf("操作流水:\n");
for(i=0;i<m;i++)
printf("%s\n",strInfo[i]);
fflush(stdin);
printf("按下任意键进行下一步。。。。。。\n");
getchar();
if(getApple(appes,chns,strInfo)==-1)return -1;
if(k)showFrame(appes,chns,strInfo),k--;
return 1;
}
int getApple(APPE *appes,CHN *chns,char (*strInfo)[100])
{
static int i=0,aflag,cflag;
int j,indexSave;
if(appes==NULL||chns==NULL) return -1;
if(chns[i].n==2)i++;//当前小朋友拿够2个,换下一个小朋友
if(i==m)return 1;//所有人均拿过,结束递归
aflag=0;
for(j=0;j<n;j++)
if(appes[j].status==0) {aflag=1;break;}
if(aflag==0) return 1;//所有苹果均拿完,结束递归
indexSave=-1;
cflag=0;
for(j=0;j<n;j++)
{
if(appes[j].status==0 && appes[j].height<=chns[i].height)
{
cflag=1;
indexSave=j;
if(rand()%2)//每次发现,有50%概率拿取,如所有可拿苹果都没选中,选最后发现的目标
break;
}
}
if(cflag)//小朋友拿起一个苹果的过程
{
appes[indexSave].status=1;
//改变苹果初始图像
sprintf(appes[indexSave].aframe[6]," ");
chns[i].appes[chns[i].n]=&appes[indexSave];
chns[i].n++;
if(chns[i].n==1)
{
//改变小朋友初始图像
sprintf(chns[i].cframe[0]," %c%c/ ",3,1);
sprintf(strInfo[i],"编号%d的小朋友拿取了1个苹果(编号%d)\n",chns[i].cid,chns[i].appes[0]->aid);
}
if(chns[i].n==2)
{
//改变小朋友初始图像
sprintf(chns[i].cframe[0]," %c%c%c ",3,1,3);
sprintf(strInfo[i],"编号%d的小朋友拿取了2个苹果(编号%d和编号%d)\n",chns[i].cid,chns[i].appes[0]->aid,chns[i].appes[1]->aid);
}
}
if(cflag==0 && chns[i].n==0) sprintf(strInfo[i],"编号%d的小朋友没有能拿到的苹果,非常沮丧!\n",chns[i].cid),i++;
if(cflag==0 && chns[i].n==1) i++;
return getApple(appes,chns,strInfo);
}
int orderChnByHeight(CHN *chns)
{
CHN chnTemp;
int i,j;
chnTemp.appes=(APPE **)malloc(sizeof(APPE*)*2);
if(!chnTemp.appes) return -1;
else
{
chnTemp.appes[0]=chnTemp.appes[1]=NULL;
if(chns)
for(i=0;i<m-1;i++)
for(j=i+1;j<m;j++)
if(chns[i].height>chns[j].height)
chnTemp=chns[i],chns[i]=chns[j],chns[j]=chnTemp;
}
free(chnTemp.appes);
return 1;
}
CHN *setChns()
{
int i;
CHN *chns=NULL;
printf("请输入小朋友的个数:");
scanf("%d",&m);
chns=(CHN *)malloc(sizeof(CHN)*m);
if(!chns) return NULL;
printf("请输入%d个小朋友身高(不超过3位整数):\n",m);
for(i=0;i<m;i++)
{
chns[i].cid=i+1;
scanf("%d",&chns[i].height);
chns[i].height=chns[i].height%1000;//超出3位截取
chns[i].n=0;
chns[i].appes=(APPE **)malloc(sizeof(APPE*)*2);
if(!chns[i].appes) return NULL;
chns[i].appes[0]=chns[i].appes[1]=NULL;
//设置小朋友初始图像
sprintf(chns[i].cframe[0]," \\%c/ ",1);
sprintf(chns[i].cframe[1]," / \\ ");
sprintf(chns[i].cframe[2],"-----");
sprintf(chns[i].cframe[3],"高%3d",chns[i].height);
sprintf(chns[i].cframe[4],"ID%3d",chns[i].cid);
}
return chns;
}
APPE *setApps()
{
int i;
APPE *appes=NULL;
printf("请输入苹果的个数:");
scanf("%d",&n);
appes=(APPE *)malloc(sizeof(APPE)*n);
if(!appes) return NULL;
printf("请输入%d个苹果的高度(不超过3位整数):\n",n);
for(i=0;i<n;i++)
{
appes[i].aid=i+1;
scanf("%d",&appes[i].height);
appes[i].height=appes[i].height%1000;//超出3位截取
appes[i].status=0;
//设置苹果初始图像
sprintf(appes[i].aframe[0],"高%3d",appes[i].height);
sprintf(appes[i].aframe[1],"ID%3d",appes[i].aid);
sprintf(appes[i].aframe[2],"-----");
sprintf(appes[i].aframe[3]," %c ",'|');
sprintf(appes[i].aframe[4]," %c ",'|');
sprintf(appes[i].aframe[5]," %c ",'|');
sprintf(appes[i].aframe[6]," %c ",3);
}
return appes;
}
怎么判断最多能摘到几个呢,什么情况下最多,只能摘两次那只能判断两次呀,摘到或者摘不到就结束了
欢迎追问
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[10000],b[10000];
int flag[10000];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<m;i++)
scanf("%d",&b[i]);
sort(a,a+n);
sort(b,b+m);
int ans=0;
for(int i=0,j=0;i<n;i++,j=0)
{
while(j<m)
{
if(b[j]>=a[i]&&flag[j]<=1)
{
++ans;
++flag[j];
break;
}
else
++j;
}
if(j>n)
break;
}
return !printf("%d\n",ans);
}
另一种更快的方法:
#include<stdio.h>
#include<algorithm>
inline int read()
{
register int x=0,f=1;
register char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
inline void write(register int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
int a[100000],b[100000];
int main()
{
int n=read(),m=read();
for(register int i=0;i<n;i++)
a[i]=read();
for(register int i=0;i<m;i++)
b[i]=read();
std::sort(a,a+n);
std::sort(b,b+m);
int top=0,ans=0;
for(register int i=0;i<m;i++)
{
if(top>=n)break;
if(a[top]<=b[i])++top,++ans;
if(top>=n)break;
if(a[top]<=b[i])++top,++ans;
}
write(ans);
return 0;
}
追问怎么判断最多能摘到几个呢,什么情况下最多,只能摘两次那只能判断两次呀,摘到或者摘不到就结束了
追答判断最多能摘到几个只需枚举每个苹果,判断当前苹果是否有人能摘到且此人采摘次数小等1(最多只能摘2次)。
flag数组是用来判断每个人采摘次数的,每个人每摘一次,flag数组就加一,只有flag数组小等1且当前人的高度大等当前苹果高度,这个人才能摘。
苹果高度和人的高度前面已经sort排序过了(默认从小到大),所以每次只会让能摘到当前个苹果的人中最矮的那个人去摘,保证最优。