一道c语言的题目。急求大神解答。

假设我们有2n张牌,它们以1,2,...,n,n+1,...,2n编号并在开始时保持着这种顺序。一次洗牌就是将牌原来的次序变为n+1,1,n+2,2,...,2n,n,也... 假设我们有 2n 张牌,它们以 1, 2, ..., n, n+1, ..., 2n 编号并在开始时保持着这种顺序。一次洗牌就是将牌原来的次序变为 n+1, 1, n+2, 2, ..., 2n, n,也就是将原来的前 n 张牌放到位置 2, 4, ..., 2n,并且将余下的 n 张牌按照他们原来的次序放到奇数位置 1, 3, ..., 2n-1。已经证明对于任何一个自然数 n,这 2n 张牌经过一定次数的洗牌就回到原来的次序。但我们不知道对于一个特定的 n,需要几次洗牌才能将牌洗回原来的次序。

输入:
牌张数的一半n,即初始情况下一共有2n张牌,n为int型整数

输出:
将牌洗回原来的次序所需要的洗牌次数
这是我的程序。为什么输入100以上的数就会无效内存引用呢?
#include<stdio.h>
int f(int n,int a[],int b[])
{
int j,i,c[2000];
for(i=0;i<2*n;i++) c[i]=a[i];
for(i=0,j=1;i<n;i++,j=j+2) a[j]=c[i];
for(j=0;i<2*n;i++,j=j+2) a[j]=c[i];
for(i=0;i<2*n;i++)
{
if(a[i]!=b[i]) return (1+f(n,a,b));
}
if(i==2*n) return 1;
}
int main()
{
int i,n,a[2000],b[2000];
scanf("%d",&n);
for(i=0;i<2*n;i++) a[i]=i;
for(i=0;i<2*n;i++) b[i]=i;
printf("%d\n",f(n,a,b));
return 0;
}
展开
 我来答
听不清啊
高粉答主

2016-05-23 · 说的都是干货,快来关注
知道顶级答主
回答量:7.8万
采纳率:89%
帮助的人:1.9亿
展开全部

这是由于原来的程序采用了递归,而且递归程序中的局部变量有较大的数组。当递归层数太多时,就会造成系统栈溢出,而导致程序崩溃。

以下的程序改为非递归的,就不会再有此现象:

#include<stdio.h> 

void f(int n,int a[],int b[]) 

 int j,i,c[20000]; 

  for(i=0;i<2*n;i++) c[i]=a[i]; 

   for(i=0,j=1;i<n;i++,j=j+2) a[j]=c[i]; 

   for(j=0;i<2*n;i++,j=j+2) a[j]=c[i]; 

int main() 

   int i,n,a[20000],b[20000],num=0;         //做到20000张牌也能正确出解

 scanf("%d",&n); 

    for(i=0;i<2*n;i++) a[i]=i; 

  for(i=0;i<2*n;i++) b[i]=i; 

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

  {

    f(n,a,b);

num++;

for(i=0;i<2*n;i++)

 if(a[i]!=b[i])break;

}

printf("%d\n",num);  

   return 0; 

}

金钱和命运
2020-06-11
知道答主
回答量:9
采纳率:0%
帮助的人:6993
展开全部
//采纳答案很对,但是函数可以少传入一个变量,for循环可以合并下
#include<stdio.h>
void f(int n,int a[])
{
int j,i,c[20000];
for(i=0; i<2*n; i++) c[i]=a[i];
for(i=0,j=1; i<n; i++,j=j+2) a[j]=c[i];
for(j=0; i<2*n; i++,j=j+2) a[j]=c[i];
}
int main()
{
int i,n,a[20000],b[20000],num=0,flag=1; //做到20000张牌也能正确出解
scanf("%d",&n);
for(i=0; i<2*n; i++)
{
a[i]=i;
b[i]=i;
}
for(i=0; i<n+n;)
{
f(n,a);
num++;
for(i=0; i<2*n; i++)
{
if(a[i]!=b[i]) break;
}
}
printf("%d\n",num);
return 0;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式