2017ACM暑期多校联合训练 - Team 1 1011 HDU 6043 KazaQ's Socks (找规律)

本文解析了一道关于袜子循环穿的问题,给出了详细的解决思路和C++代码实现。问题描述为:有n双编号从1到n的袜子,每天选择编号最小的一双穿,当只剩下最后一双干净袜子时,则将所有脏袜子清洗后再穿。文章通过找规律的方法,总结出了除前n天外,袜子编号呈现特定循环模式的特点,并提供了高效的求解方案。

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

题目链接

Problem Description

KazaQ wears socks everyday.

At the beginning, he has n pairs of socks numbered from 1 to n in his closets.

Every morning, he puts on a pair of socks which has the smallest number in the closets.

Every evening, he puts this pair of socks in the basket. If there are n−1 pairs of socks in the basket now, lazy KazaQ has to wash them. These socks will be put in the closets again in tomorrow evening.

KazaQ would like to know which pair of socks he should wear on the k-th day.

Input
The input consists of multiple test cases. (about 2000)

For each case, there is a line contains two numbers n,k (2≤n≤109,1≤k≤1018).

Output
For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.

Sample Input
3 7
3 6
4 9

Sample Output
Case #1: 3
Case #2: 1
Case #3: 2

分析:
有n双袜子分别编号1~n,每天从干净的袜子中选择一双编号最小的袜子穿,如果干净的袜子只剩下一双了,就把所有穿过的袜子洗干净接着穿,选择的时候仍然满足上面的规则,问第k天穿的袜子的编号是多少?

这就是一个找规律的题,我们通过两组数据来看一下他的规律:
数据1: 3 7
那每天穿的袜子的序列就是:
1 2 3 1 2 1 3 那么第七天穿的袜子就是编号3,
如果我们接着往下看的话,就会发现整个序列是这样子的:
1 2 3 1 2 1 3 1 2 1 3 1 2 1 3······
就会发现除了前n天以外,穿的袜子的编号的循环节是 1 2 1 3。

数据2: 4 9
那每天穿的袜子的序列就是:
1 2 3 4 1 2 3 1 2 那么第七天穿的袜子就是编号2,
如果我们接着往下看的话,就会发现整个序列是这样子的:
1 2 3 4 1 2 3 1 2 4 1 2 3 1 2 4 1 2 3 1 2 4 ······
就会发现除了前n天以外,穿的袜子的编号的循环节是 1 2 3 1 2 4。

通过上面的两组数据我们就可以发现他的循环规律:
我们将每个循环节的前半部分和后半部分分开,会发现最后一位是在n和n-1直接,前面的就是第几次去袜子对于(n-1)的一个余数。

#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
    long long int n,k,Case=1;
    {
        while(~scanf("%lld%lld",&n,&k))
        {
            printf("Case #%lld: ",Case++);
            if(k<=n)                 ///直接输出来就行了
                printf("%lld\n",k);
            else
            {
                long long int num=(k-n)/(n-1);///num表示第几次取半循环
                long long int yu=(k-n)%(n-1);///yu表示在半循环中取第几个
                if(num%2==0)///偶数次
                {
                    if(yu==0)///最后一个
                        printf("%lld\n",n);
                    else
                        printf("%lld\n",yu);
                }
                else///奇数次
                {
                   if(yu==0)///最后一个
                        printf("%lld\n",n-1);
                    else
                        printf("%lld\n",yu);
                }
            }
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/cmmdc/p/7238751.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值