[NOIP2019模拟赛]夹缝

夹缝

问题描述:

二维空间内有两面相对放置的,向无限远延伸的镜子,以镜子的方向及其法向量建立坐标系,我们选
定一个法向量方向下面称“上”。
在镜子上的整数位置,存在着一些传感器,传感器不影响光线的反射,光线仍旧满足反射定律(即入
射角等于出射角)。
你可以在两面镜子上各选定一个整数位置的点 A B,并从其中一个点向另一个射出一条光线,我
们希望接收到光线的传感器数量尽可能的多。

考试打了暴力+随机骗分。然而还没有一些巨佬直接小范围暴力求答案取max来的分高...

首先是结论:①假设步长为k,那么步长为(2t+1)k的时候覆盖的点是没有直接K来的优秀的,简单易证,感性理解一下

      ②若起点为s,步长为k,那么一边的经过x的条件是:x=s+2tk,另一边经过y的条件是y=s+k+2tk(t∈Z)

所以只要求步长为$2^i$时就好了

 1 #pragma GCC optimize("Ofast")
 2 #include<bits/stdc++.h>
 3 #define qqq register
 4 using namespace std;
 5 inline int read(){
 6     int ans=0,f=1;char chr=getchar();
 7     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
 8     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
 9     return ans*f;
10 }const int M=300005;
11 int n,m,h,res,p[M],q[M],c[M],ans;
12 inline void cmax(int &x,int y){if(x<y) x=y;}
13 int Calc(int x,int z){
14     x%=z;
15     if(x<0) x+=z;
16     return x;
17 }
18 int Calc(int x,int y,int z){
19     x%=z;
20     x+=y;
21     if(x<0) x+=z;
22     if(x>=z) x-=z;
23     return x;
24 }
25 int main(){
26     freopen("mirror.in","r",stdin);
27     freopen("mirror.out","w",stdout);
28     n=read(),m=read(),h=read();ans=2;
29     for(qqq int i=1;i<=n;++i) p[i]=read();
30     for(qqq int i=1;i<=m;++i) q[i]=read();
31     int ppp=log(1e9)/log(2);
32     for(qqq int i=0;i<=ppp;++i){
33         int t1=1<<i;
34         int t2=1<<i+1;
35         int tot=0;
36         for(qqq int j=1;j<=n;++j) c[++tot]=Calc(p[j],t2);
37         for(qqq int j=1;j<=m;++j) c[++tot]=Calc(q[j],t1,t2);
38         sort(c+1,c+tot+1);
39         for(qqq int j=1,k;j<=tot;){
40             for(k=j;k<=tot&&c[k]==c[j];++k);
41                 cmax(ans,k-j);j=k;
42         }
43     }cout<<ans;
44     return 0;
45 }
原文地址:https://www.cnblogs.com/zhenglw/p/11190915.html