题目链接
题意:给你n*n的地图,假若你在(x,y)这个点,那么下次你可以到达点
((x+dx)%n,(y+dy)%n),其中gcd(dx,n)==gcd(dy,n)==1,然后告诉地图上有m个点有苹果树,问你怎么选择起点可以经过最多的苹果树,多解输出一组即可
解法:gcd(dx,n)==gcd(dy,n)==1这个条件的存在,我们先看一维的情况,假设dx=3,n=5;
从0出发0–>3–>1–>4–>2–>0,
从1出发1–>4–>2–>0–>3–>1
从2出发2–>0–>3–>1–>4–>2
从3出发3–>1–>4–>2–>0–>3
…..
可以发现每次的循环长度都是n,而且经过所有的点[0,n-1],这是一维的情况,二维类比一维,
有n条长度是n的路径,每个路径看做一个集合,然后计算每个点(x,y)与集合X[x],的偏移量t,那么这个点就是集合的。
再找最大值。
#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=1000005;
const LL inf=1LL<<60;
const LL mod=1e9+7;
int X[maxn];
int num[maxn];
int main() {
int n,m,dx,dy;
cin>>n>>m>>dx>>dy;
int x=0,y=0;;
for(int i=0;i<n;i++){
X[x]=y;
x=(x+dx)%n;
y=(y+dy)%n;
}
for(int i=0;i<m;i++){
int x,y;scanf("%d%d",&x,&y);
int t=y-X[x];
if(t<0)t+=n;
num[t]++;
}
int ans=0,Y=0;
for(int i=0;i<n;i++)if(ans<num[i]){
Y=i;ans=num[i];
}
printf("0 %d\n",Y);
return 0;
}