2013 Multi-University Training Contest 3

来源:互联网 发布:网络安全技术是什么 编辑:程序博客网 时间:2024/06/05 14:31

全队就我一开始敲出了一道签到题1007The Unsolvable Problem。。。之后就各种被虐啊。。。

没算法,只能说是YY出来的。题意就是让你求出n=a+b,a和b的最大的最小公倍数,首先考虑奇数,当奇数被拆为n=x+(x+1)时,x和(x+1)为互质数,直接相乘得到答案,而偶数的话,2直接特判==1,再看其它偶数,当偶数除以2为奇数时,上下加减1肯定为两个偶数,最小公倍数必然不能取最大,所以应上下加减2,然后相乘得到答案。而当偶数除以2为偶数时,上下加减1互为奇数(互质),然后相乘得到答案。

#include<iostream>#include<cmath>#include<cstring>#include<string>#include<algorithm>#include<iomanip>#include<cstdio>using namespace std;int main(){    int t;    __int64 n;    cin>>t;    while(t--)    {        cin>>n;        if(n==2)        {            cout<<1<<endl;            continue;        }        if(n%2==1)        {            cout<<(n/2)*(n/2+1)<<endl;        }        else        {            if((n/2)%2==0)            {                cout<<(n/2-1)*(n/2+1)<<endl;            }            else            {                cout<<(n/2-2)*(n/2+2)<<endl;            }        }    }    return 0;}

1011 Sad Love Story

比赛中后期一直在敲这题,发现是个求多次最近点对的问题,一开始用分治法求,O(n^2logn),复杂度太高TLE,后来学长写了KD-tree,发现还是TLE,赛后看标程才理解了,不需要求多次,先求一次全部点的最近点对,对于之前的点就不需要算了,然后去掉了一部分点,直到找到最后点为止。解题报告说KD-tree也可以做,但是要常数优化,表示不懂。。。。

#include<iostream>#include<cmath>#include<cstring>#include<string>#include<algorithm>#include<iomanip>#include<cstdio>#define MAXN 500010using namespace std;struct xl{    long long x,y,id,in;    xl(long long xx=0,long long yy=0,long long iin=0)    {        x=xx;        y=yy;        in=iin;    }}P[MAXN],p[MAXN],tmpt[MAXN];struct zx{    long long f,s;}e;long long dd(xl a,xl b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}bool cmp1(xl a,xl b){    if(a.x != b.x)    {        return a.x<b.x;    }    else    {        return a.y<b.y;    }}bool cmp2(xl a,xl b){    return a.y<b.y;}zx XLL(long long lw,long long hi){    int i,j,k;    long long d=(1LL<<60),mid,d1,d2;    if(lw==hi)    {        e.f=lw;        e.s=hi;        return e;    }    if(lw+1==hi)    {        e.f=lw;        e.s=hi;        return e;    }    mid=(lw+hi)/2;    zx pr1=XLL(lw,mid);    zx pr2=XLL(mid+1,hi);    if(pr1.f==pr1.s)    {        d1=(1LL<<60);    }    else    {        d1=dd(p[pr1.f],p[pr1.s]);    }    if(pr2.f==pr2.s)    {        d2=(1LL<<60);    }    else    {        d2=dd(p[pr2.f],p[pr2.s]);    }    zx ans;    if(d1<d2)    {        ans=pr1;    }    else    {        ans=pr2;    }    d=min(d1,d2);    k=0;    for(i=lw; i<=hi; i++)    {        if((p[mid].x-p[i].x)*(p[mid].x-p[i].x)<=d)        {            tmpt[k++]=p[i];        }    }    sort(tmpt,tmpt+k,cmp2);    for(i=0; i<k; i++)    {        for(j=i+1; j<k&&(tmpt[j].y-tmpt[i].y)*(tmpt[j].y - tmpt[i].y) < d; j++)        {            if(d>dd(tmpt[i],tmpt[j]))            {                d=dd(tmpt[i],tmpt[j]);                ans.f=tmpt[i].id;                ans.s=tmpt[j].id;            }        }    }    return ans;}int main(){    int t,i;    long long n,ax,ay,bx,by,cx,cy,w,Max,x,y,ans;    scanf("%d",&t);    while(t--)    {        scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&n,&ax,&bx,&cx,&ay,&by,&cy);        P[0]=xl(0,0,0);        for(i=1; i<=n; i++)        {            x=(P[i-1].x*ax+bx)%cx;            y=(P[i-1].y*ay+by)%cy;            P[i]=xl(x,y,i);        }        w=n;        ans=0;        while(w>1)        {            for(i=0; i<w; i++)            {                p[i]=P[i+1];            }            sort(p,p+w,cmp1);            for(i=0; i<w; i++)            {                p[i].id=i;            }            zx pr=XLL(0,w-1);            Max=max(p[pr.f].in,p[pr.s].in);            ans+=(w-Max+1)*dd(p[pr.f],p[pr.s]);            w=Max-1;        }        printf("%I64d\n",ans);    }    return 0;}


1008 Pieces

版刷题,可我们没过。。。敲了一上午,用状压暴力枚举做得,,,2^16的个数

#include<iostream>  #include<cmath>  #include<cstring>  #include<string>  #include<algorithm>  #include<iomanip>  #include<cstdio>  #define MAXN 1<<16  using namespace std;  int dp[MAXN],q[MAXN];inline void RD(int &ret){    char c;    do    {        c=getchar();    }    while(c<'0'||c>'9');    ret=c-'0';    while((c=getchar())>='0'&&c<='9')    {        ret=ret*10+(c-'0');    }}  int main()  {      int t,i,j,l,l1,f,w;      char a[22];      RD(t);    while(t--)      {          scanf("%s",a);          l=strlen(a);          l1=1<<l;          for(i=1; i<l1; ++i)          {              dp[0]=MAXN;//初始化,容易出错。。。              w=0;              for(j=0; j<=l; ++j)              {                  if(i&(1<<j))                  {                      q[w++]=j;                  }              }              f=0;              w=w-1;              for(j=0; j<w/2; ++j)              {                  if(a[q[j]]!=a[q[w-j]])                  {                      dp[i]=w+1;                      f=1;                      break;                  }              }              if(f==0)              {                  dp[i]=1;              }              for(j=i;j;j=(j-1)&i)              {                  //cout<<(j^i)<<' '<<dp[(j^i)]<<endl;                  dp[i]=min(dp[i],dp[j]+dp[j^i]);              }              //cout<<dp[i]<<endl;          }          printf("%d\n",dp[l1-1]);     }      return 0;  }
加了个输入优化。。


1010 No Pain No Game

树状数组维护,数据结构的题表示一直不太会,而且也看不太出来。。。

#include<iostream>#include<cmath>#include<cstring>#include<string>#include<algorithm>#include<iomanip>#include<cstdio>using namespace std;int n,c[50001];int a[50001],b[50001],ac[50001];inline void RD(int &ret)//输入优化挺重要{    char c;    do    {        c=getchar();    }    while(c<'0'||c>'9');    ret=c-'0';    while((c=getchar())>='0'&&c<='9')    {        ret=ret*10+(c-'0');    }}int lowbit(int x){    return x&(-x);}int add(int n){    int sum=0;    while(n>0)    {        sum=max(sum,c[n]);        n-=lowbit(n);    }    return sum;}void updata(int i,int x){    while(i<=n)    {        c[i]=max(c[i],x);        i+=lowbit(i);    }}struct xl{    int lw,hi,id;} s[50001];bool cmp(xl x,xl y){    return x.lw>y.lw;}int main(){    int i,t,m,j,k;    RD(t);    while(t--)    {        RD(n);        for(i=1; i<=n; ++i)        {            RD(a[i]);        }        RD(m);        for(i=0; i<m; ++i)        {            RD(s[i].lw);            RD(s[i].hi);            s[i].id=i;        }        sort(s,s+m,cmp);        i=n;        j=0;        memset(b,0,sizeof(b));        memset(c,0,sizeof(c));        while(j<m)        {            for(; i>0&&i>=s[j].lw; --i)            {                for(k=1; k*k<=a[i]; ++k)                {                    if(a[i]%k==0)                    {                        if(b[k]!=0)                        {                            updata(b[k],k);                        }                        b[k]=i;                        if(a[i]/k!=k)                        {                            if(b[a[i]/k]!=0)                            {                                updata(b[a[i]/k],a[i]/k);                            }                            b[a[i]/k]=i;                        }                    }                }            }            while(j<m&&s[j].lw>i)            {                ac[s[j].id]=add(s[j].hi);                j++;            }        }        for(i=0; i<m; ++i)        {            printf("%d\n",ac[i]);        }    }    return 0;}



我实在太水了。。。

原创粉丝点击