UVA-10710 Skyscraper Floors (找规律+幂取模)

题目大意:题目中给了一种数的定义,根据定义,让判断一个给定的数是不是这种数。题中叫这种数为吉米数,定义如下:对序列1,2,3,,,,n,做n-1次SF变换(对该变换的解释在下文),如果能得到原序列,则n为吉米数。

SF变换:若n为偶数,以n=10为例,一次SF变换是这样的

    1,2,3,4,5,6,7,8,9,10—>1,2,3,4,5  6,7,8,9,10—>6,1,7,2,8,3,9,4,10,5  此为偶数的一次SF变换,第二次变换是基于新序列的,以此类推。

    若n为奇数,以n=9为例,一次SF变换是这样的

    1,2,3,4,5,6,7,8,9—>1,2,3,4  5,6,7,8,9—>5,1,6,2,7,3,8,4,9   此为奇数的一次SF变换,第二次变换也是基于新序列的,以此类推。

 

题目分析:根据题中的提示,偶数不是吉米数。如果是吉米数,则相应的序列中的任一元素的位置周期都是一样的,所以只需考虑1。最终找到1的位置有如下规律:pos=(2^t)%n,其中t为变换的次数。所以只需判断(2^(n-1))%n=1是否成立即可。

 实际上还是幂取模!!!

代码如下:

 1 # include<iostream>
 2 # include<cstdio>
 3 # include<cstring>
 4 # include<algorithm>
 5 using namespace std;
 6 # define ll long long
 7 ll mypow(ll a,ll b,ll m)
 8 {
 9     if(b==0)
10         return 1;
11     if(b==1)
12         return a%m;
13     ll u=mypow(a,b/2,m);
14     u*=u;
15     u%=m;
16     if(b&1)
17         u*=a;
18     return u%m;
19 }
20 bool is(ll x)
21 {
22     ll pos=mypow(2,x-1,x);
23     return pos==1;
24 }
25 int main()
26 {
27     ll n;
28     while(scanf("%lld",&n)&&n!=-1){
29         if(is(n))
30             printf("%lld is a Jimmy-number\n",n);
31         else
32             printf("%lld is not a Jimmy-number\n",n);
33     }
34     return 0;
35 }
View Code

 

posted @ 2015-08-06 22:44  20143605  阅读(310)  评论(0编辑  收藏  举报