
C语言大神帮帮我啊!!帮帮忙,我悬赏高分帮帮忙!!在线等待
短信传情(message.pas/c/cpp)【问题描述】文艺青年Setanda灰常强大,同时搞到了很多妹纸,情人节到了,Setanda觉得给他的妹纸们发短信送去祝福。粗...
短信传情
(message.pas/c/cpp)
【问题描述】
文艺青年Setanda 灰常强大,同时搞到了很多妹纸,情人节到了,Setanda
觉得给他的妹纸们发短信送去祝福。粗心的Setanda 同学发出短信后才发现,可
能不小心把给妹纸发的短信发错了。比如给1 号妹纸的短信发到了2 号妹纸的手
机上,给2 号妹纸发的短信发到了3 号妹纸的手机上……结果可想而知,妹纸们
很生气,所有收到错误短信的妹纸都将抛弃Setanda 同学。求Setanda 同学被全
部妹纸抛弃的方案数有几种。由于方案数可能过大,输出方案数对95917 取余后
的结果。
【输入】
输入文件message.in 共一行;
第一行为人数N,表示N 个妹纸。
【输出】
输出文件仅message.out 共一行,包含一个数,Setanda 同学被全部妹纸抛弃的
方案数。由于方案数可能过大,输出方案数对95917 取余后的结果。
【输入样例1】
2
【输出样例1】
1
【样例1 说明】
1-2,2-1;
【输入样例2】
3
【输出样例2】
2
【样例1 说明】
1-2,2-3,3-1;
1-3,2-1,3-2;
【数据范围】
对于30%数据,有1<=n<=10;
对于50%数据,有1<=n<=20;
对于100%数据,有1<=n<=100。 展开
(message.pas/c/cpp)
【问题描述】
文艺青年Setanda 灰常强大,同时搞到了很多妹纸,情人节到了,Setanda
觉得给他的妹纸们发短信送去祝福。粗心的Setanda 同学发出短信后才发现,可
能不小心把给妹纸发的短信发错了。比如给1 号妹纸的短信发到了2 号妹纸的手
机上,给2 号妹纸发的短信发到了3 号妹纸的手机上……结果可想而知,妹纸们
很生气,所有收到错误短信的妹纸都将抛弃Setanda 同学。求Setanda 同学被全
部妹纸抛弃的方案数有几种。由于方案数可能过大,输出方案数对95917 取余后
的结果。
【输入】
输入文件message.in 共一行;
第一行为人数N,表示N 个妹纸。
【输出】
输出文件仅message.out 共一行,包含一个数,Setanda 同学被全部妹纸抛弃的
方案数。由于方案数可能过大,输出方案数对95917 取余后的结果。
【输入样例1】
2
【输出样例1】
1
【样例1 说明】
1-2,2-1;
【输入样例2】
3
【输出样例2】
2
【样例1 说明】
1-2,2-3,3-1;
1-3,2-1,3-2;
【数据范围】
对于30%数据,有1<=n<=10;
对于50%数据,有1<=n<=20;
对于100%数据,有1<=n<=100。 展开
3个回答
展开全部
#include "stdio.h"
#include "stdlib.h"
long count=0;
void Swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void Perm(int list[],int k,int m)
//k表示前缀的位置,m是要排列的数目.
{
if(k==m-1)
//前缀是最后一个位置,此时打印排列数.
{
int tag=0;
for(int i=0;i<m;i++)
{
if(list[i]==i+1)
{
tag=1;
break;
}
}
if(!tag)
{
count++;
if(count==95917)
count=0;
}
}
else
{
for(int i=k;i<m;i++)
{
//交换前缀,使之产生下一个前缀.
Swap(list[k],list[i]);
Perm(list,k+1,m);
//将前缀换回来,继续做上一个的前缀排列.
Swap(list[k],list[i]);
}
}
}
int main()
{
FILE *fp1,*fp2;
int n;
int *list;
if((fp1=fopen("message.in","r"))==NULL)
{
printf("open message.in error\n");
exit(1);
}
if((fp2=fopen("message.out","w"))==NULL)
{
printf("open message.out error\n");
exit(1);
}
fscanf(fp1,"%d",&n);
list=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++)
list[i]=i+1;
Perm(list,0,n);
fprintf(fp2,"%ld",count);
fclose(fp1);
fclose(fp2);
return 0;
}
#include "stdlib.h"
long count=0;
void Swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void Perm(int list[],int k,int m)
//k表示前缀的位置,m是要排列的数目.
{
if(k==m-1)
//前缀是最后一个位置,此时打印排列数.
{
int tag=0;
for(int i=0;i<m;i++)
{
if(list[i]==i+1)
{
tag=1;
break;
}
}
if(!tag)
{
count++;
if(count==95917)
count=0;
}
}
else
{
for(int i=k;i<m;i++)
{
//交换前缀,使之产生下一个前缀.
Swap(list[k],list[i]);
Perm(list,k+1,m);
//将前缀换回来,继续做上一个的前缀排列.
Swap(list[k],list[i]);
}
}
}
int main()
{
FILE *fp1,*fp2;
int n;
int *list;
if((fp1=fopen("message.in","r"))==NULL)
{
printf("open message.in error\n");
exit(1);
}
if((fp2=fopen("message.out","w"))==NULL)
{
printf("open message.out error\n");
exit(1);
}
fscanf(fp1,"%d",&n);
list=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++)
list[i]=i+1;
Perm(list,0,n);
fprintf(fp2,"%ld",count);
fclose(fp1);
fclose(fp2);
return 0;
}
展开全部
亲,你这是肿么了。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
这是利用错排的知识解答 可以去看下错排公式!
更多追问追答
追问
能直接给我答案么?谢谢
追答
1. 一个简单的递推公式
n 个不同元素的一个错排可由下述两个步骤完成:
第一步,“错排” 1 号元素(将 1 号元素排在第 2 至第 n 个位置之一),有 n - 1
种方法。
第二步,“错排”其余 n - 1 个元素,按如下顺序进行。视第一步的结果,若 1
号元素落在第 k 个位置,第二步就先把 k 号元素“错排”好, k
号元素的不同排法将导致两类不同的情况发生:( 1 ) k 号元素排在第 1
个位置,留下的 n - 2 个元素在与它们的编号集相等的位置集上“错排”,有 f(n -2)
种方法;( 2 ) k 号元素不排第 1 个位置,这时可将第 1 个位置“看成”第 k
个位置,于是形成(包括 k 号元素在内的) n - 1 个元素的“错排”,有 f(n - 1)
种方法。据加法原理,完成第二步共有 f(n - 2)+f(n - 1) 种方法。
根据乘法原理, n 个不同元素的错排种数
f(n) = (n-1)[f(n-2)+f(n-1)] (n>2) 。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询