Codeforces Round #509 (Div. 2) F. Ray in the tube(思维)
题目链接:http://codeforces.com/contest/1041/problem/F
题意:给出一根无限长的管子,在二维坐标上表示为y1 <= y <= y2,其中 y1 上与 n 个点,y2 上有 m 个点,问在 y1 和 y2 上各选一个点,从其中一个点出发射到另外一个点并无限反射下去,可以触碰到 y1 和 y2 上的点和最大为多少。
题解:考虑射出去的线打到对面板上所需要走的距离dd,假设出发点为0,则打在自己这边上的点的坐标为{0,2d,4d,6d,8d,...}{0,2d,4d,6d,8d,...},打在对面板上的则是{d,3d,5d,7d,9d,...}{d,3d,5d,7d,9d,...}。若将距离改为k⋅d,则两个点集分别为{0,2kd,4kd,6kd,8kd,...}{0,2kd,4kd,6kd,8kd,...},{kd,3kd,5kd,7kd,9kd,...}{kd,3kd,5kd,7kd,9kd,...},可以发现若k为奇数,两个集合中的点都只会减少不会增加,kk为偶数时则有存在增减的情况,因此设k=2^l一定是最优的。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define LL __int128 5 #define ull unsigned long long 6 #define mst(a,b) memset((a),(b),sizeof(a)) 7 #define mp(a,b) make_pair(a,b) 8 #define pi acos(-1) 9 #define pii pair<int,int> 10 #define pb push_back 11 const int INF = 0x3f3f3f3f; 12 const double eps = 1e-6; 13 const int MAXN = 1e5 + 10; 14 const int MAXM = 2e6 + 10; 15 const ll mod = 1e9 + 7; 16 17 int a[MAXN], b[MAXN]; 18 map<ll,int>mp; 19 20 int main() 21 { 22 #ifdef local 23 freopen("data.txt", "r", stdin); 24 // freopen("data.txt", "w", stdout); 25 #endif 26 int n,m,y; 27 scanf("%d%d",&n,&y); 28 for(int i = 0; i < n; i++) scanf("%d",&a[i]); 29 scanf("%d%d",&m,&y); 30 for(int i = 0; i < m; i++) scanf("%d",&b[i]); 31 int ans = 2; 32 ll d = 1, dd = 1; 33 for(int i = 0; i <= 32; i++) { 34 mp.clear(); 35 dd <<= 1; 36 for(int j = 0; j < n; j++) mp[a[j] % dd]++; 37 for(int j = 0; j < m; j++) mp[(b[j] + d) % dd]++; 38 for(auto it : mp) ans = max(ans, it.second); 39 d <<= 1; 40 } 41 printf("%d\n",ans); 42 return 0; 43 }