(The 11th Zhejiang Provincial Collegiate Programming Contest )What day is that day?

链接:http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5248

题目:

What day is that day?

Time Limit: 2 Seconds       Memory Limit: 65536 KB

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.


解题思路:

这是一道数论的题目,关键是找到规律。这里要用到的几个公式:(a +b) % m = (a  % m + b % m) % m;  (a * b) % m = ((a % m) * (b % m)) % m; 费马小定理:n ^ n % m = (n % m )  ^  n; 在这里我们可以发现:(n ^ 7) % 7 = n (n < 7), (7 ^ 7) % 7 = 0; 

设 T1 = ( (a ^ a ) + (b ^ b)  + .... + (g ^ g)  ) % 7 

( (a + 7) ^ (a + 7) + (b + 7)  ^ (b + 7) + ... +  (g + 7)  ^ ( g + 7)) % 7  = (a ^ (a + 7) + b ^ (b + 7) + ... + g ^ (g + 7)) % 7= ( (a ^ a ) * (a ^ 7) + (b ^ b) * (b ^ 7)  + .... + (g ^ g)  * (g ^ 7) % 7  =  ((a ^ a ) * a + (b ^ b) * b + .... + (g ^ g)  * g  ) % 7 ,) (a = 1, 8, 15, ...)

通过这样的计算,我们可以得到:T7 = T1;

我们可以发现这样的一个式子的周期为6,所以总的周期是6 * 7 = 42;


代码:

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;

int a[6][7] = 
{
1,4,6,4,3,1,0,
1,1,4,2,1,6,0,
1,2,5,1,5,1,0,
1,4,1,4,4,6,0,
1,1,3,2,6,1,0,
1,2,2,1,2,6,0
};
int b[43];

int main()
{	
	int t;
	while(~scanf("%d", &t))
	{
		while(t--)
		{
			int n;
			scanf("%d", &n);
			
			int m = 0;
			for(int i = 0; i < 6; i++)
			{
				for(int j = 0; j < 7; j++)
				{
					m += a[i][j];
					b[7 * i + j + 1] = m % 7;
				}
			}
	
			int sum = 0, num = n / 42;
			m = n % 42;
			sum += ((num % 7) * 6) % 7;
			sum += b[m];
			sum = sum % 7;

			switch(sum)
			{
				case 0: puts("Saturday");  break;
				case 1: puts("Sunday");    break;
				case 2: puts("Monday");    break;
				case 3: puts("Tuesday");   break;
				case 4: puts("Wednesday"); break;
				case 5: puts("Thursday");  break;
				case 6: puts("Friday");    break;
			}
		}
	}
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值