Codeforces.1041F.Ray in the tube(思路)

题目链接

\(Description\)

有两条平行于\(x\)轴的直线\(A,B\),每条直线上的某些位置有传感器。你需要确定\(A,B\)轴上任意两个位置\(x_A,x_B\),使得一条光线沿\(x_A\to x_B\)射出(碰到\(A,B\)后反射),能够碰到的传感器数量最多是多少。

\(Solution\)

由光的反射定律可知,光束上相邻两个点的水平距离是确定的,设这个距离为\(dx\)(纵坐标就没有什么用了)。
那么会被从\(x_A\)出发的光束照到的点,在\(A\)轴上满足坐标为\(x_A+2k\cdot dx\);在\(B\)轴上满足坐标为\(x_A+(2k-1)\cdot dx\)。

我们发现若\(dx=a\cdot b\),\(a\)为奇数,\(b\)为偶数,则\(dx'=\frac{dx}{a}=b\)会碰到所有\(dx\)会碰到的点,即不会更差。
所以存在奇数因子的\(dx\)没有必要判断。那么我们只需要判断\(dx=2^l,l\geq 0\)的情况。这一共有\(\log(10^9)\)种。

对于一个确定的\(dx\),如果\(A\)轴上两个点\(x_1,x_2\)同时被碰到,那么满足\(x_1\equiv x_2\mod{(2 \cdot dx)}\);如果\(B\)轴上两个点\(x_1,x_2\)同时被碰到,那么满足\(x_1+dx\equiv x_2\mod{(2 \cdot dx)}\)。
所以我们将两个点集按\(\mod 2dx\)的余数分组,点数最多的一组就是当前最优解。sort或直接map都可以。
复杂度\(O(n\log n\log(10^9))\)。

注意\(ans\)初始是\(2\)。。

//171ms 1500KB
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 150000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=2e5+5;

int n,A[N],tmp[N],Now;
char IN[MAXIN],*SS=IN,*TT=IN;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}

int main()
{
    int n=read(); read();
    for(int i=1; i<=n; ++i) A[i]=read();
    int m=read(),tot=n+m; read();
    for(int i=n+1; i<=tot; ++i) A[i]=read();

    int ans=2/*!*/; tmp[tot+1]=2e9+1;
    for(int dx=1; dx<=int(1e9); dx<<=1)
    {
        int mod=dx<<1;
        for(int i=1; i<=n; ++i) tmp[i]=A[i]%mod;
        for(int i=n+1; i<=tot; ++i) tmp[i]=(A[i]+dx)%mod;
        std::sort(tmp+1,tmp+1+tot);
        for(int i=1,las=1; i<=tot; ++i)
            if(tmp[i+1]!=tmp[i]) ans=std::max(ans,i-las+1), las=i+1;
    }
    printf("%d\n",ans);

    return 0;
}

原文地址:https://www.cnblogs.com/SovietPower/p/9681586.html

时间: 2024-10-09 15:22:09

Codeforces.1041F.Ray in the tube(思路)的相关文章

Codeforces 1041F Ray in the tube (看题解)

Ray in the tube 感觉是套路题.. 如果确定一个差值x我们如何取确定答案呢, 我们把a[ i ] -> a[ i ] % (2 * x), 把b[ i ] -> (b[ i ] + k) % (2 * x), 值相同的都能同时射到. 同时我们能发现, 对于一个差值x如果它有奇数因子, 把它除掉之后会更优, 所以我们要check的x只有2的幂次. #include<bits/stdc++.h> #define LL long long #define fi first

codeforces 630C - Lucky Numbers 递推思路

630C - Lucky Numbers 题目大意: 给定数字位数,且这个数字只能由7和8组成,问有多少种组合的可能性 思路: 假设为1位,只有7和8:两位的时候,除了77,78,87,88之外还哇哦加上前面只有7和8的情况,一共是6位.所以递推式不难写出dp[i]=pow(2,i)+dp[i-1]; 代码: #include <bits/stdc++.h> using namespace std; typedef long long ll; ll ans[56]; void init ()

Codeforces 552C Vanya and Scales(思路)

题目大概说有101个质量w0.w1.w2.....w100的砝码,和一个质量m的物品,问能否在天平两边放物品和砝码使其平衡. 哎,怎么没想到..注意到w0.w1.w2.....w100—— 把m转化成w进制数,枚举每一位: 如果第i位是0那OK: 如果是1那就要把砝码wi放在天平另一边抵消: 如果是w-1那就要把砝码wi放到天平同一边,使其变为0并进位,这时第i+1位的权+1: 而如果是其他情况,那么肯定不能平衡了. 1 #include<cstdio> 2 #include<cstri

CodeForces 518A - Chewbaсca and Number(思路)

题意:给你两个长度相同的字符串,输出一个长度与它俩相同,且字典序位于两者之间(不可与其中一者相同)的字符串,若不存在则输出"No such string".(输入保证字典序第一个严格小于第二个,且长度相同) 水题,让最后一个加一个单位的字典序然后检查是否符合条件即可(注意为'z'的时候要进位,若长度超过则也不符合) #include<cstdio> #include<cstring> #include<cctype> #include<cstd

【Codeforces】542C - Idempotent functions(思路)

题目大意思: 给定一个数的next值,问最小的k值,使得每次进行k次操作得到的数都是一样的. 将每个位置i记为点i 记circle[i]为从i出发出现环的环内元素,我们的任务就是求这些数的最小公倍数lcm,还要考虑'6'型循环的情况,这个我们只需要求最大的多余长度之后对lcm向上取整就好了 #include<cstdio> #include<stack> #include<cstring> #include<algorithm> using namespac

Codeforces 722C(并查集 + 思维)

题目链接:http://codeforces.com/problemset/problem/722/C 思路: 题目给的操作数从第 1 个到第 N 个数是删除原数组中的一个数, 那么反过来从后往前就是增加原数组中的一个数, 每增加一个值, 那么就有四种情况: 第一种和前后都不连续, 即自成一个集合; 第二种:和前面的数连续, 即和前一个数在一个集合; 第三种和之后一个数连续, 即和之后的一个数在一个集合; 第四种既和前面一个数连续也和后面一个数连续,那么说明前后两个集合被这个数合并成一个集合.

Codeforces 589F F. Gourmet and Banquet(二分+贪心)

题目地址:http://codeforces.com/problemset/problem/589/F 思路:先贪心按照右端点值排序(先把对后面影响最小的菜吃掉),二分吃每道菜的时间即可. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=105; const int maxt=1e5+50

Codeforces Round #177 (Div. 1) C. Polo the Penguin and XOR operation(贪心)

题目地址:http://codeforces.com/problemset/problem/288/C 思路:保证位数尽量大的情况下使得每二进制位均为一的情况下结果最大,从后向前枚举(保证位数尽量大),num表示该数i二进制有几位,x即为使得与i异或后每二进制位均为一的数,v[x]标记是否使用过该数,若未使用则与i搭配. #include<cstdio> #include<cmath> #include<cstring> #include<iostream>

Codeforces 474D Flowers

http://codeforces.com/problemset/problem/474/D 思路:F[i]=F[i-1]+(i>=K)F[i-k] 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 const int Mod=1000000007; 7 int K,sum[200005]