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
",ans);
42     return 0;
43 }
原文地址:https://www.cnblogs.com/scaulok/p/9677272.html