NOJ [1104] 报数游戏

  • n个人站成一行玩一个报数游戏。所有人从左到右编号为1到n。游戏开始时,最左边的人报1,他右边的人报2,编号为3的人报3,等等。当编号为n的人(即最右边的人)报完n之后,轮到他左边的人(即编号为n-1的人)报n+1,然后编号为n-2的人报n+2,以此类推。当最左边的人再次报数之后,报数方向又变成从左到右,依次类推。 
    为了防止游戏太无聊,报数时有一个特例:如果应该报的数包含数字7或者是7的倍数,他应当用拍手代替报数。下表是n=4的报数情况(X表示拍手)。当编号为3的人第4次拍手的时候,他实际上数到了35。 

    给定n,m和k,你的任务是计算当编号为m的人第k次拍手时,他实际上数到了几。 

    通过几次的推理,不难得到
    第奇数次报数到第偶数次拍手c+=2*n-2*m;
    相反 c+=2*m-2;

     另外,n==m或者m==1也要处理
    #include<stdio.h>
    #include<string.h>
    
    bool cmplex( 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))
        {
        	if(m==0 && n==0 && k==0)
        	  break;
            int i=1,cnt=0;
            long long temp=m;
            if(temp%7==0 || (temp/10==7 ||temp%10==7))
                cnt++;
            int period = 2 * n - 2;
            if(n==m || m==1)
            {
            	for( int i = m; ; i += period ) 
            	  if(cmplex(i))
                    {  
                        cnt++;  
                        if( cnt == k )  
                        {  
                            printf("%d\n", i);  
                            break;  
                        }  
                    }  
            }
            else
            {
            while(cnt!=k)
            {
                if(i%2)  //i是第奇数次报数
                {
                    temp+=2*n-2*m;
                    i++;
                }
                else
                {
                    temp+=2*m-2;
                    i++;
                }
                if(cmplex(temp))
                  cnt++;
            }
            printf("%lld\n",temp);
            }
        }
        return 0;
    }





你可能感兴趣的:(NOJ [1104] 报数游戏)