第一题是约瑟夫问题。
int i,j,k,s1=1,w,p[100];
for(i=1;i<=100;i++) /*对p[0]--p[99]进行赋值,内容为位置的编号*/
p[i-1]=i;
for(i=100;i>=2;i--)
{s1=(s1+10-1)%i; /*设现在共有i个人,此句保证当数数到i-1后 */
if(s1==0)s1=i; /*回到0 */
w=p[s1-1]; /*每次去掉一个,将其编号放入从p[99]到 */
for(j=s1;j<=i-1;j++) /*p[0]的一个空位上 */
p[j-1]=p[j];
p[i-1]=w; }
int i,j,k,s1=1,w,p[100];
for(i=1;i<=100;i++) /*对p[0]--p[99]进行赋值,内容为位置的编号*/
p[i-1]=i;
for(i=100;i>=2;i--)
{s1=(s1+10-1)%i; /*设现在共有i个人,此句保证当数数到i-1后 */
if(s1==0)s1=i; /*回到0 */
w=p[s1-1]; /*每次去掉一个,将其编号放入从p[99]到 */
for(j=s1;j<=i-1;j++) /*p[0]的一个空位上 */
p[j-1]=p[j];
p[i-1]=w; }
int i,j,n,len;
for(i=0;i<maxline;i++)/*maxline是一篇要加密文章的最大行*/
{len=strlen(xx[i]); /*求出串xx[i]的长度 */
n=-1;
for(j=0;j<len;j++)
{n+=key; /*这3行可变为n=(n+key)%len;*/
if(n>=len) /*记数位超过该字符串的长度,回到起始位后记数*/
n-=len;
str[n]=xx[i][j];}/*第key个字符时,把xx[i]的第j个字符放入str */
str[len]='\0'; /*给str加结尾 */
strcpy(xx[i],str)} /*将处理过的解密行,存入原来加密行 */
什么时候 (s1==0)s1=i呢?请帮帮忙吧?感谢!!
int i,j,k,s1=1,w,p[100];
//初始化数组
for(i=1;i<=100;i++)
p[i-1]=i;
//因为有100个数,每个都应该做一次因而需要99次的循环
//最后一个不用计数。
for(i=100;i>=2;i--)
{
//因为每10个拿出一个,
//%i是因为:i是剩下i个超过i时应从头记数。
s1=(s1+10-1)%i;
//由于上式计算中s1+10-1=i时s1=0,因而要将s1改为i。
if(s1==0)s1=i;
//暂保存本次出圈的值。
w=p[s1-1];
//将本次出圈以后的人依次向前移动。
for(j=s1;j<=i-1;j++)
p[j-1]=p[j];
//将本次出圈的人放在队尾。
p[i-1]=w;
}
最后结果是:从后向前看,依次是第1、2、...100个出圈的人的编号。第二个程序和第一个类似。另:什么时候 (s1==0)s1=i呢?
比如说第10个出圈时就会发生。
此时i=91,s1=82+10-1,s1%91=0。
应该是91出圈,但s1变成了0因而就应该有
if(s1==0)s1=i。
for(i=1;i<=100;i++) ..//这里的循环就是数据的初始化
p[i-1]=i;
for(i=100;i>=2;i--)//这里开始第二个循环
{s1=(s1+10-1)%i;//这里算的是他该不该出队
if(s1==0)s1=i;//由题意知如果s1==0 那么这个人的后面所有的人都顺次
w=p[s1-1];//向前提一位,而这个向前提一位的操作正是下一个循环的意思!
for(j=s1;j<=i-1;j++)
p[j-1]=p[j];
p[i-1]=w; }