It's Saturday today, what day is it after 11 + 22 + 33 + ... + NN days?
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
There is only one line containing one integer N (1 <= N <= 1000000000).
Output
For each test case, output one string indicating the day of week.
Sample Input
2 1 2
Sample Output
Sunday Thursday
Hint
A week consists of Sunday, Monday, Tuesday, Wednesday, Thursday, Friday and Saturday.
Author: ZHOU, Yuchen
Source: The 11th Zhejiang Provincial Collegiate Programming Contest
解析:循环节。
预备知识:(a*b) % x=( (a%x) * (b%x) ) %x。
那么根据上方的公式就可以将1+2^2+....+n^n化简:
1 + 2^2 + 3^3 + 4^4 + 5^5 + 6^6 + 0
1 + 2^2*2^7 + 3^3*3^7 + 4^4*4^7 + 5^5*5^7 + 6^6*6^7 + 0
。。。。。。
以 2 为例,(2^7)%7=2,那么上述第二列向下的数对 7 取模后,依次就为:4 1 2 4 1 2 。 。 。
出现循环节:4 1 2
我们可以发现他们的和恰好就为 7 ,那么就得到上述第二列向下依次求和,再对 7 取模后为: 4 5 0 4 5 0 。。。。
出现循环节:4 5 0
对其余各列依次查找循环节后,就可以再将上式化简为:
1 + 4 + 6 + 4 + 3 + 1 + 0
2 + 5 + 3 + 6 + 4 + 0 + 0
3 + 0 + 1 + 0 + 2
4 2 6
5 5 5
6 0 0
0
好了,基本思路就这样,代码见下方:
#include<cstdio>
using namespace std;
int a[7][10]={0,0,0,0,0,0,0,0,0,0,
0,1,2,3,4,5,6,0,0,7,
0,4,5,0,0,0,0,0,0,3,
0,6,3,1,2,5,0,0,0,6,
0,4,6,0,0,0,0,0,0,3,
0,3,4,2,6,5,0,0,0,6,
0,1,0,0,0,0,0,0,0,2};
char s[10][10]={"Saturday",
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday"};
void work()
{
int n,i,j,k,ans=0;
scanf("%d",&n);
k=n/7,j=n%7;
for(i=1;i<=j;i++)ans+=a[i][(k+1)%a[i][9]];
if(k>0)for(i=j+1;i<=6;i++)ans+=a[i][k%a[i][9]];
printf("%s\n",s[ans%7]);
}
int main()
{
freopen("1.in","r",stdin);
int t,i,j,k;
while(scanf("%d",&t)!=EOF)
for(i=1;i<=t;i++)work();
return 0;
}