【UKIEPC2015 M】【暴力匹配+SET去重】Milestone Counter 匀速行驶 合法的里程碑起点

来源:互联网 发布:大唐移动 知乎 编辑:程序博客网 时间:2024/05/29 17:13
#include<stdio.h> #include<iostream>#include<string.h>#include<vector>#include<sstream>#include<algorithm>#include<map>#include<set>using namespace std;typedef long long LL;const int N=1e3+10;int n,m;LL t[N],a[N],d[N],b[N];LL gcd(LL x,LL y){    return y==0?x:gcd(y,x%y);}set<LL>sot;set<LL>::iterator it;int main(){    while(~scanf("%d%d",&n,&m))    {        for(int i=1;i<=n;i++)scanf("%lld",&t[i]);        for(int i=1;i<n;i++)a[i]=t[i+1]-t[i];        for(int i=1;i<=m;i++)scanf("%lld",&d[i]);        for(int i=1;i<m;i++)b[i]=d[i+1]-d[i];        sot.clear();        for(int i=1;i<m;i++)        {            if(i+n-1>m)break;//起点可以是[1,m-1],段数有n-1,即i+n-1-1<=m-1,即i+n-1<=m            LL g=gcd(a[1],b[i]);            LL zi=a[1]/g;            LL mu=b[i]/g;            bool flag=1;            for(int j=2;j<n;j++)            {                LL g=gcd(a[j],b[i+j-1]);                LL x=a[j]/g;                LL y=b[i+j-1]/g;                if(x!=zi||y!=mu)                {                    flag=0;                    break;                }            }            if(flag)sot.insert(b[i]);        }        printf("%d\n",sot.size());        for(it=sot.begin();it!=sot.end();it++)printf("%lld ",*it);        puts("");    }    return 0;}/*【trick&&吐槽】1,不同的数筛掉,用set很方便2,要防止区间溢出3,判定是否a/b=x/y,直接把两个分数都化成最简,然后比较"分子=分子,分母=分母"即可【题意】一共有n(1e3)个里程碑,告诉你这n个里程碑代表的点的坐标(抽象到x轴正半轴上,坐标为[0,1e15]的整数)然后我们驾车,匀速驶过了连续m个里程碑。忘记了驶过的是哪m个,但是我们记得驶过这m个里程碑的时刻(时刻也为[0,1e15]的整数)问你所有可能的车速的种类,并输出所有情况下行车驶过的第一段路程的长度。【类型】暴力,gcd【分析】看到这题n的范围,我们想到O(n^2)的做法即可实现这道题。就是枚举匹配的首位点,然后向后延展,严格匹配m-1个区间。如果这m-1个区间的时间与距离的比例都相同。那么这就可能是一个合法的区间。于是这样暴力即可AC这道题【时间复杂度&&优化】O(n^2)【数据】input4 121 2 4 56 8 12 18 26 28 30 34 36 37 39 40output21 2input5 101 2 3 4 50 1 2 3 4 5 6 7 8 9output11input3 61 2 411 12 15 19 24 30output0input2 31123456789000 11234567890075 8 13output23 5*/

1 0
原创粉丝点击