A. Hilbert’s Hotel(数学)

传送门

\(看了一下网上都没什么题解,自己写一篇吧,对你有帮助的话留个言吧~\)

\(\color{Orange}{----------------------分割------------------------}\)

\(\color{Green}{一、分析问题}\)

\(对于给定的n和数组a,其实是有循环存在的\)

\(比如[0,n)模n后余数必定是[0,n)\)

\([n,2n)模n后余数必定是[0,n)\)

\(现在我们的目的是判断是否所有数都是互不相等的。\)

\(\color{Orange}{二、举例子发现规律}\)

\(拿这组样例来说\)

\(4\)
\(5\ 5\ 5\ 1\)

\(按照我们上面的循环节,把操作后得到的数写出来\)

\([0,3]:5\ 6\ 7\ 4\)
\([4,7]:9\ 10\ 11\ 8\)
\(.............\)

\(可以发现,[4,7]就是由[0,3]都加n得来的,这很容易理解\)

\(那么我们可以把所有循环节看成由[0,3]加上nk得来的\)

\(所以现在的问题是已知集合={5+nk,6+nk,7+nk,4+nk},求是否有相同的数字\)

\(因为要互不相同,所以5、6、7、4模n后应该互不相等\)

\(\color{Red}{为什么?因为如果模n后相等,就一定存在某个k使得x_1=x_2+kn}\)

\(\color{Purple}{三、算法实现}\)

\(问题到这里应该就很简单了\)

\(先处理出[0,n)操作后得到的数字(也就是先处理一个循环节)\)

\(然后对处理后的每个数对n求余,如果余数互不相等说明不存在重复的数字\)

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+9;
int n,t;
int a[maxn],b[maxn];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<n;i++)
            b[i]=i+a[i%n];//处理第一个循环节 
        for(int i=0;i<n;i++) b[i]=(b[i]%n+n)%n;//对n取余 
        sort(b,b+n);//排序后,如果余数互不相等,必定是0,1,2...n-1 
        int flag=1;
        for(int i=0;i<n;i++)
        if(b[i]!=i) flag=0;
        if(flag)    cout<<"YES";
        else    cout<<"NO";
        cout<<endl;
    }
}

原文链接: https://www.cnblogs.com/iss-ue/p/12844330.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    A. Hilbert's Hotel(数学)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/346982

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午4:15
下一篇 2023年3月2日 上午4:16

相关推荐