What day is that day? ZOJ - 3785

本文介绍了一个算法问题的解决方案,该问题涉及确定从特定日期开始一系列天数后的星期几。通过使用模运算和预先计算的方法,文章提供了一种高效的方法来解决这个问题,避免了直接相加可能带来的巨大计算负担。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

What day is that day?

 ZOJ - 3785 

It's Saturday today, what day is it after 11 + 22 + 33 + ... + NNdays?

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.

找规律题的一种技巧

 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;


#define ll long long
const int N = 1e6 + 7;
const int M = 500;
const int mod = 7;

ll ksm(ll a, ll b, ll c) {
	ll ans = 1;
	a %= c;
	while (b > 0) {
		if (b&1) ans = (ans * a) % c;
		a = a*a%c;
		b>>=1;
	}
	return ans;
}

int sum[N];
int next_[N];

void print(int op) {
	if (op == 1) {
		puts("Monday");
	} else if ( op == 2) {
		puts("Tuesday");
	} else if (op == 3) {
		puts("Wednesday");
	} else if (op == 4) {
		puts("Thursday");
	} else if (op == 5) {
		puts("Friday");
	} else if (op == 6) {
		puts("Saturday");
	} else {
		puts("Sunday");
	}
}

void get_next(int len) {
	
	int i = 0, j = -1;
	next_[0] = -1;
	while (i <= len) {
		if (j == -1 || sum[i] == sum[j]) {
			++i, ++j;
			next_[i] = j;
		} else j = next_[j];
	}
	
}





int main() {
	
	sum[0] = 5;//因为是模7所以星期六是5、星期五是4... 
	for (int i = 1; i <= M; ++i) {
		sum[i] = (ksm(i, i, mod) + sum[i-1]) % mod;
	}
	//printf ("%d\n", sum[294]); // 5
	//get_next(M);
	
	
	int t;
	scanf ("%d", &t);
	while (t--) {
		
		int n;
		scanf ("%d", &n);
		print(sum[n%294]+1);
		//getchar();
		//暴力法找循环节 
//		for (int i = 1; i <= n; ++i) {
//			int ok = 1;
//			for (int j = 1; j <= i; ++j) {
//				if (sum[j] != sum[i+j]) {
//					ok=0;
//					break;
//				}
//			}
//			if (ok) {
//				printf ("%d\n", i);
//				break;
//			}
//		}
		// kmp的next找循环节 
		//for (int i =1; i <= n; ++i) {
			//printf ("%d\n", sum[i]);
			//printf ("%d\n", next_[i]);
		//	int len = i - next_[i];
		//	if (len!=i && i%len == 0 ) {
		//		printf ("%d %d\n", i, i/len);
		//		break;
		//	}
		//}
	//	puts("over");
	}
	
	
	
	
	
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值