[NOIP赛前复习第二期]复赛考试技巧与模版

来源:互联网 发布:中国战略知乎 编辑:程序博客网 时间:2024/05/02 01:49

考试技巧

1.拿到考卷首先通看题目,按自己感觉的难度排序(普及一般是1-2-3-4了~还是相信出题老师不会坑我的2333)
2.一般来说,普及组前两道题比较简单(大水题啊233~),但是通常坑很多,例如NOIP2000计算器的改良一题….非常坑,需要注意1.未知数从A-z中的任意一个字母2.字母系数为1时可以省略….因此要多读3遍题,切记仔细读题,一个字都不能放过。before that think twice and double check you code.(多想几遍然后反复检查代码了~)
3.处理完T1,T2就来到有(ju)趣(ken)的T3了~一般来说普及组的T3 还是挺水的通常思考5~20分钟就能思考出来。然而实现的坑也不比T1,T2。通常T3会让我们进行一些模运算和long long运算。别看这些都这么简单,然而这就是出题老师将100分坑成20分的得力工具啊233~先说long long:在一个运算公式里,要得到long long的结果,一般要让加入运算的所有都开long long(一定要注意是全开long long!!),否则100变50-。再说取模运算:并不是所有的运算都可以乱%的,一定要先判断是否对结果有影响再%,另外记住一点——能%的地方一定不要放过。
4.接着就是T4了,这种题一般都不能得满分的,毕竟还是有难度(像我这种蒟蒻就更做不起了233…),建议是按题目的数据范围一步步优化,尽量拿更高的分数

考试模版

考试专供

随机数据生成器

#include<iostream>#include<cstdlib>#include<ctime>#include<algorithm>using namespace std;int num[1000005];int main(){    srand(time(NULL));    freopen("begining.out","w",stdout);    int n=(rand()%10000)+1;    printf("%d\n",n);    for(int i=1;i<=n;i++)    {        num[i]=rand()%10000;    }    sort(num+1,num+n+1);    for(int i=1;i<=n;i++)printf("%d ",num[i]);}

对拍程序

bat版

先新建一个记事本文档;
在文档中写:

@echo off:loopbegining.exe > data.outstart.exe < data.out > start.outstd.exe < data.out > std.outfc start.out std.outif not errorlevel 1 goto looppausegoto loop

c++版(推荐)

#include<iostream>  #include<windows.h>  using namespace std;  int main()  {      int testdata=100;    while(1)      {          testdata--;        system("data.exe > data.txt");          system("biaoda.exe < data.txt > biaoda.txt");           system("test.exe < data.txt > test.txt");          if(system("fc test.txt biaoda.txt"))   break;      }      if(testdata==0) cout<<"no error"<<endl;      else cout<<"error"<<endl;      system("pause");      return 0;  }  

读入优化

int read()  {      int x=0,f=1;char s=getchar();      while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}      while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}      return x*f;  }  

算法——排序

sort版

#include<iostream>#include<algorithm>using namespace std;long long n,a[100000];int main(){    scanf("%lld",&n);    for(int i=0;i<n;i++) cin>>a[i];    sort(a,a+n);    for(int i=0;i<n-1;i++) cout<<a[i]<<' ';    cout<<a[n-1];    return 0;}

快速排序

从小到大

#include<iostream>#include<cstdio>#include<cmath>#include<algorithm> using namespace std;int a[100005];int l,n,m,cont,c;void quicksort(int x,int y){    int l=x,r=y,mid;    mid=a[(l+r)/2];    while(l<=r)    {        while(a[l]<mid)l++;        while(a[r]>mid)r--;        if(l<=r){swap(a[l],a[r]);l++;r--;}    }    if(x<r)quicksort(x,r);    if(y>l)quicksort(l,y);}int main(){    int i;    scanf("%d",&n);    for(i=1;i<=n;i++)scanf("%d",&a[i]);    quicksort(1,n);    for(i=1;i<=n;i++)printf("%d ",a[i]);}

归并排序

从小到大

#include<iostream>#include<cstdio>using namespace std;int a[100005],s[100005];long long cont;void merge(int st,int m,int ov){    int l=st,r=m+1,q=0;    while(l<=m&&r<=ov)    {        if(a[l]<=a[r])s[q++]=a[l++];        else {s[q++]=a[r++];cont+=m-l+1;}    }    while(l<=m)s[q++]=a[l++];    while(r<=ov)s[q++]=a[r++];    for(int i=st;i<=ov;i++)a[i]=s[i-st];}void mergesort(int st,int ov){    if(st<ov)    {        int mid=(st+ov)/2;        mergesort(st,mid);        mergesort(mid+1,ov);        merge(st,mid,ov);    }}int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%d",&a[i]);    mergesort(1,n);    for(int i=1;i<=n;i++)printf("%d ",a[i]);    printf("\n");    //printf("%lld",cont);//本输出用于求逆序对}

数据结构

优先队列

#include<queue>#include<iostream>#include<cstdio>#include<algorithm>using namespace std;priority_queue<int> QAQ;int n,x,a;int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d",&x);        if(x==1){scanf("%d",&a);QAQ.push(-a);}        if(x==2)printf("%d\n",-QAQ.top());        if(x==3)QAQ.pop();    }}

并查集

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int n,m,fa[10005],z,x,y;int find(int p){    if(fa[p]!=p)fa[p]=find(fa[p]);    return fa[p];}void bin(int x1,int y1){    fa[x1]=y1;}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        fa[i]=i;    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&z,&x,&y);        int ta=find(x),tb=find(y);        if(z==1)        {            if(ta==tb)continue;            else bin(ta,tb);        }        if(z==2)        {            if(ta==tb)printf("Y\n");            else printf("N\n");        }    }}

根据两种遍历顺序确定树结构

#include<cstdio>#include<iostream>#include<climits>#include<algorithm>#include<queue>#include<cstring>using namespace std;string s1,s2;void xfind(int len1,int re1,int len2,int re2){    int m=s2.find(s1[len1]);    if(m>len2)xfind(len1+1,len1+m-len2,len2,m-1);    if(m<re2)xfind(len1+m-len2+1,re1,m+1,re2);    printf("%c",s1[len1]);}int main(){    cin>>s1>>s2;    xfind(0,s1.length()-1,0,s2.length()-1);    return 0;}

图论

有向图的DFS

#include<iostream> #include<algorithm> #include<climits> #include<vector>using namespace std; struct node{     int v,next; }a[20010];int b[205];int n,m,maxx,s,num;bool visit[205]; int read() {     int x=0,f=1;char s=getchar();     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}     return x*f; } void fpush(int from,int to){    a[++num].v=to,a[num].next=b[from],b[from]=num;}void dfs(int j) {    visit[j]=1;maxx++;    for(int i=b[j];i;i=a[i].next)        if(visit[a[i].v]==0)dfs(a[i].v); } int main() {     n=read();m=read();     for(int i=1;i<=m;i++)     {         int u,v;         u=read();v=read();        fpush(u,v);    }    s=read();    dfs(s);     printf("%d",maxx); } 

无向图的BFS

#include<iostream>#include<cstring>using namespace std;int n,m,k,head=0,tail=1,a[205],s;bool b[205],ks[205][205];int main(){    memset(b,0,sizeof(b));    memset(a,0,sizeof(a));    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)    {        int u,v;        scanf("%d%d",&u,&v);        ks[u][v]=1;        ks[v][u]=1;    }    scanf("%d",&s);    printf("%d",s);    a[1]=s;    b[s]=1;    while(head!=tail)    {        head++;        int kk=a[head];        for(int i=1;i<=n;i++)        {            if(!b[i]&&ks[kk][i]==1)            {                   printf(" %d",i);                tail++;                a[tail]=i;                b[i]=1;             }        }    }    return 0;}

哈密顿环

#include<iostream>#include<cstdio>#include<algorithm>#include<vector>using namespace std;vector<int>a[205];bool visit[205],flag=1;int x,n,ans,start=1;void dfs(int s,int deep){    if(deep==n)ans++;    for(int i=0;i<a[s].size();i++)        if(!visit[a[s][i]])        {            visit[a[s][i]]=1;            dfs(a[s][i],deep+1);            visit[a[s][i]]=0;        }}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)        {            scanf("%d",&x);            if(x==1)a[i].push_back(j);        }    for(int i=1;i<=n;i++)    visit[i]=1,dfs(i,1),visit[i]=0;    printf("%d",ans);}

欧拉回路

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;bool k[105][105],flag=1;int x,n,du,sum,ff[10005],start=1,p;void dfs(int s){    for(int i=1;i<=n;i++)        if(i!=s&&k[s][i])        {            k[s][i]=0;k[i][s]=0;            dfs(i);        }    ff[++p]=s;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        du=0;        for(int j=1;j<=n;j++)        {            scanf("%d",&x);            if(x==1){k[i][j]=1;du++;}            else k[i][j]=0;        }        if(du%2==1){if(!sum)start=i;sum++;}    }    if(sum>2){printf("No Solution!\n");return 0;}    dfs(start);    printf("%d",ff[p]);    for(int i=p-1;i>=1;i--)printf(" %d",ff[i]);}

最小生成树

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;struct node{    int x,y,price;}a[200005];int n,m,p,u,v,father[5005],x,y,num,ans,ksum;bool cmp(node s1,node s2){    return s1.price<s2.price;}int read()  {      int x=0,f=1;char s=getchar();      while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}      while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}      return x*f;  }  int find(int p){    if(father[p]!=p)father[p]=find(father[p]);    return father[p];}void bin(int p1,int p2){    father[p2]=p1;}int main(){    n=read();m=read();    for(int i=1;i<=n;i++)bin(i,i);    for(int i=1;i<=m;i++)            u=read(),v=read(),a[++num].price=read(),a[num].x=u,a[num].y=v;    sort(a+1,a+num+1,cmp);    for(int i=1;i<=num;i++)    {        if(ksum==n-1)break;        int s1=find(a[i].x),s2=find(a[i].y);        if(s1!=s2)        {            bin(s1,s2);            ans+=a[i].price;            ksum++;        }    }    if(ksum==n-1)printf("%d\n",ans);    else printf("orz\n");}

SPFA

#include<cstdio>#include<queue>#include<climits>using namespace std;int b[10005],vis[10005],now,x,y,z,xnext,cnt,m,n,s,en,d[10005],cont,flag=1;queue<int>a;struct node{    int next,to,w;}e[500005];void fpush(int u,int v,int w){    e[++cnt].next=b[u];    e[cnt].w=w;    e[cnt].to=v;    b[u]=cnt;}void SPFA(){    a.push(s);    d[s]=0;    while(!a.empty())    {        cont++;        now=a.front();        a.pop();        vis[now]=0;        for(int i=b[now];i;i=e[i].next)        {            xnext=e[i].to;            if(d[now]+e[i].w<d[xnext])            {                d[xnext]=d[now]+e[i].w;                if(!vis[xnext])                {                    a.push(xnext);                    vis[xnext]=true;                }            }        }    }}int main(){    scanf("%d%d%d",&n,&m,&s);    for(int i=1;i<=n;i++)        d[i]=INT_MAX/2;    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&x,&y,&z);        fpush(x,y,z);    }    SPFA();    for(int i=1;i<=n;i++)        if(d[i]!=INT_MAX/2)printf("%d ",d[i]);        else printf("2147483647 ");    return 0;}

数论

gcd

int gcd(int m,int n)  {      while(m>0)      {int c=n%m;n=m,m=c;}    return n;  } 

线性筛素数

#include<iostream> #include<cstdio>#include<cmath>#include<cstring>using namespace std;int n,m,l,r;bool isPrime[10000005];int main(){    scanf("%d%d",&m,&n);    memset(isPrime,0,sizeof(isPrime));    isPrime[1]=true;    for(int i=2;i<=sqrt(m);i++)    {        if(isPrime[i]==0)        {            for(int j=2*i;j<=m;j+=i)            isPrime[j]=true;        }    }    for(int i=1;i<=n;i++)    {        scanf("%d",&r);        if(!isPrime[r])        printf("Yes\n");        else         printf("No\n");    }}
阅读全文
1 0