[NOIP2017赛前复习第二期]复赛考试技巧与模版-普及组

考试技巧

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
:loop
begining.exe > data.out
start.exe < data.out > start.out
std.exe < data.out > std.out
fc start.out std.out
if not errorlevel 1 goto loop
pause
goto 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");
    }
}
上一篇:web项目报outmemory错误解决方案


下一篇:vue项目的骨架及常用组件介绍