Light oj 1104

本文介绍了一个基于生日悖论的问题,即在一个包含特定数量的人群中,至少两人拥有相同生日的概率达到0.5所需的最少人数。文章提供了一段C语言代码,用于计算在不同天数的年份中这一临界值的具体数值。

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

I - I
Time Limit: 2000MS      Memory Limit: 32768KB      64bit IO Format: %lld & %llu

Description

Sometimes some mathematical results are hard to believe. One of the common problems is the birthday paradox. Suppose you are in a party where there are 23 people including you. What is the probability that at least two people in the party have same b

irthday? Surprisingly the result is more than 0.5. Now here you have to do the opposite. You have given the number of days in a year. Remember that you can be in a different planet, for example, in Mars, a year is 669 days long. You have to find the minimum number of people you have to invite in a party such that the probability of at least two people in the party have same birthday is at least 0.5.

Input

Input starts with an integer T (≤ 20000), denoting the number of test cases.

Each case contains an integer n (1 ≤ n ≤ 105) in a single line, denoting the number of days in a year in the planet.

Output

For each case, print the case number and the desired result.

Sample Input

2

365

669

Sample Output

Case 1: 22

Case 2: 30

思路:

两个人生日相同的情况太多,用逆向思维,通过循环先算出任意两人生日不同的概率,若概率值小于等于0.5就可以了,结束循环;

计算任意两人生日不同的概率,用一个for循环,先算第一个人的是n*1.0 / n,第二个人的是(n-1) *1.0 / n,第三个人的是(n-2) *1.0 / n 等等;i从0开始,总人数为i+1(包括他自己),要邀请的人数是 i ;

代码:

#include<stdio.h>
#include<string.h>
int main()
{
	int t,n,mm=1;
	scanf("%d",&t);
	while(t--)
	{
		double ans=1.0;
		scanf("%d",&n);
		int i;
		for(i=0;;i++)
		{
			ans*=(n-i)*1.0/n;
			if(ans<=0.5)
			break;
		}
		printf("Case %d: %d\n",mm++,i);
	}
	return 0;
}



### OJ 1104 题目:链表倒序实现 对于OJ平台上的题目1104——链表倒序,目标是将单向链表中的元素按照相反的顺序重新排列。以下是具体的解决方案。 #### 方法一:迭代法反转链表 通过遍历整个链表,在每次访问新节点时调整指针方向来完成链表的反转操作。此方法的空间复杂度为O(1),因为只用了常量级别的额外空间;而时间复杂度则为O(N),其中N表示链表长度。 ```cpp ListNode* reverseList(ListNode *head){ ListNode *prev = nullptr; while(head != nullptr){ auto nextNode = head->next; // 记录下一个节点位置 head->next = prev; // 当前节点指向前面已经处理过的部分 prev = head; // 移动prev至当前节点 head = nextNode; // 继续处理剩余未处理的部分 } return prev; // 返回新的头部节点 } ``` #### 方法二:递归方式反转链表 利用函数调用栈自然形成的回溯机制来进行链表反转。当到达最后一个节点之后开始逐层返回,并修改各层之间的连接关系直到回到最顶层。这种方法同样可以达到线性的运行效率但是由于涉及到大量的子过程调用所以实际性能可能不如前者稳定。 ```cpp // 定义辅助函数用于内部递归调用 void recursiveReverse(ListNode*& newHead, ListNode* cur){ if(cur -> next == NULL){ // 找到最后一个节点作为新的头结点 newHead = cur; return ; } recursiveReverse(newHead,cur->next); // 修改相邻两个节点间的链接方向 cur->next->next = cur; cur->next = NULL; } // 主接口函数 ListNode* reverseList(ListNode* head) { if(!head || !head->next) return head; ListNode* res=nullptr; recursiveReverse(res,head); return res; } ``` 两种算法都能有效地解决这个问题,选择哪种取决于具体应用场景和个人偏好。通常情况下推荐使用迭代版本因为它更加直观易于理解而且不会受到系统最大递归深度的影响[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值