下表是 n=4 的报数情况(X 表示拍手)。
当编号为 3 的人第 4 次拍手的时候。他实际上数到了 35。
| 人 | 1 | 2 | 3 | 4 | 3 | 2 | 1 | 2 | 3 |
| 报数 | 1 | 2 | 3 | 4 | 5 | 6 | X | 8 | 9 |
| 人 | 4 | 3 | 2 | 1 | 2 | 3 | 4 | 3 | 2 |
| 报数 | 10 | 11 | 12 | 13 | X | 15 | 16 | X | 18 |
| 人 | 1 | 2 | 3 | 4 | 3 | 2 | 1 | 2 | 3 |
| 报数 | 19 | 20 | X | 22 | 23 | 24 | 25 | 26 | X |
| 人 | 4 | 3 | 2 | 1 | 2 | 3 | 4 | 3 | 2 |
| 报数 | X | 29 | 30 | 31 | 32 | 33 | 34 | X | 36 |
4 3 1 4 3 2 4 3 3 4 3 4 0 0 0
17 21 27 35
一道简单的模拟题:要模拟出现的情况,主要要推出一个规律 在边界的位置时,下一个报数的位置就是 2*n-2。(我也不知道是怎么推出来的)
这样就能够推算出 每一个编号 下一个报数的位置;直接进行推断。
#include <cstdio>
#include <cstring>
bool judge(int n)//推断函数,推断是否含7,或者是7的倍数
{
if( !(n % 7) ) return true;
while(n)
{
if( n % 10 == 7 )
return true;
n /= 10;
}
return false;
}
int main()
{
int n,m,k,i;
while(scanf("%d%d%d",&n,&m,&k)&&n&&m&&k)
{
int count=0;
for(i=7;;i++)
{
if(judge(i))
{
int x=i%(2*n-2);//得出的是初始编号
if(x==0)
x=2*n-2;
if(x==m || (x>=n && 2*n-x==m ))//符合题意的情况
count++;
if(count==k)
break;
}
}
printf("%d\n",i);
}
return 0;
}
分成了两个部分进行考虑,边界情况就直接是2*n-2,中间的间隔是两个数循环变化的。
#include <cstdio>
#include <iostream>
using namespace std;
bool is7( int n )//推断
{
if( !(n % 7) ) return true;
while(n)
{
if( n % 10 == 7 ) return true;
n /= 10;
}
return false;
}
int main()
{
int n, m, k;
while( scanf("%d %d %d", &n, &m, &k) !=EOF && n+m+k )
{
int cnt = 0, period = 2 * n - 2;
if( n == m || m == 1 )//边界的情况
{
for( int i = m; ; i += period ) if( is7( i ) )
{
cnt++;
if( cnt == k )
{
printf("%d\n", i);
break;
}
}
}
else
{
int next = 2 - m;
for( int i = m; ; swap( next, i ) )//中间的情况
{
next += period;
if( is7( i ) )
{
cnt++;
if( cnt == k )
{
printf("%d\n", i);
break;
}
}
}
}
}
return 0;
}
换一种思路。直接进行模拟,依照先顺序,后倒序进行模拟;
#include <cstdio>
#include <cstring>
bool judge(int n)//推断
{
if( !(n % 7) ) return true;
while(n)
{
if( n % 10 == 7 )
return true;
n /= 10;
}
return false;
}
int main()
{
int n,m,k,i;
while(scanf("%d%d%d",&n,&m,&k)&&n&&m&&k)
{
int pos=0,count=0,flag=0;
for(i=1;i<=n;i++)//顺序处理
{
pos++;
if(i==m)
{
if(judge(pos))
count++;
if(count==k)//搜索到结果了
{
printf("%d\n",pos);
break;
}
}
if(i==n)
{
i=n-1;//进行倒序处理
for(;i>=1;i--)
{
pos++;
if(i==m)
{
if(judge(pos))
count++;
if(count==k)
{
flag=1;
printf("%d\n",pos);
break;
}
}
}
if(flag) break;
i=1;//回溯到顺序
}
}
}
return 0;
}
版权声明:本文博主原创文章,博客,未经同意不得转载。
原文:http://www.cnblogs.com/mengfanrong/p/4843201.html