Lihht OJ ---Fibsieve`s Fantabulous Birthday(找规律,数学)
1008 - Fibsieve`s Fantabulous Birthday
http://www.lightoj.com/volume_showproblem.php?problem=1008
1008 - Fibsieve`s Fantabulous Birthday
PDF (English) | Statistics | Forum |
Time Limit: 0.5 second(s) | Memory Limit: 32 MB |
Fibsieve had a fantabulous (yes, it's an actual word) birthday party this year. He had so many gifts that he was actually thinking of not having a party next year.
Among these gifts there was an N x N glass chessboard that had a light in each of its cells. When the board was turned on a distinct cell would light up every second, and then go dark.
The cells would light up in the sequence shown in the diagram. Each cell is marked with the second in which it would light up.
(The numbers in the grids stand for the time when the corresponding cell lights up)
In the first second the light at cell (1, 1) would be on. And in the 5th second the cell (3, 1) would be on. Now, Fibsieve is trying to predict which cell will light up at a certain time (given in seconds). Assume that N is large enough.
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case will contain an integer S (1 ≤ S ≤ 1015) which stands for the time.
Output
For each case you have to print the case number and two numbers (x, y), the column and the row number.
Sample Input | Output for Sample Input |
3 8 20 25 | Case 1: 2 3 Case 2: 5 4 Case 3: 1 5 |
题意很好理解,就是给你一个n(0<n<=10的15次方)
你需要通过给你的n求出,这个n在表格的第几行第几列。
为了便于分析,我们用两种颜色将它分成5个区域
每个区域的拐角都有一个关键值 key
假如说某个区域的最大值为s
那么该区域的key=s-[sqrt(s)-1]
同时两种颜色也表示两种状态(state)。
从这个图上看
state==1时也就是橙色区域里比key大的值在key 的左边的情况
state==0时也就是蓝色区域里比key大的值在key的上边的情况
这两种情况我们可以根据该区域sqrt(s)的奇偶来区分
接下来是如何判断坐标
一个区域的key的坐标为,(sqrt(s),sqrt(s)) 注明:s为该区域最大值
如果该区域的状态是state==0 你想知道一个大于key的x的坐标
那么x的坐标为(sqrt(s)-(x-key),sqrt(s))
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #define ll long long 5 6 int main() 7 { 8 int T,Case=1; 9 10 ll n; 11 scanf("%d",&T); 12 while(T--) 13 { 14 bool state; 15 scanf("%lld",&n); 16 ll s=sqrt(n); 17 ll k; 18 if(s*s<n) 19 s++; 20 k=s*s-(s-1); 21 if(s%2==0) 22 state=false;///获取该区域状态 23 else 24 state=true; 25 if(k>n) 26 { 27 ll dif=k-n; 28 if(state) 29 { 30 printf("Case %d: %lld %lld\n",Case++,s,s-dif); 31 } 32 else 33 { 34 printf("Case %d: %lld %lld\n",Case++,s-dif,s); 35 } 36 37 } 38 else if(k<n) 39 { 40 ll dif=n-k; 41 if(state) 42 { 43 printf("Case %d: %lld %lld\n",Case++,s-dif,s); 44 } 45 else 46 { 47 printf("Case %d: %lld %lld\n",Case++,s,s-dif); 48 } 49 } 50 else 51 printf("Case %d: %lld %lld\n",Case++,s,s); 52 53 } 54 return 0; 55 }View Code