2017-10-12 NOIP模拟赛

时间:2022-12-17 09:14:43

 

 

2017-10-12 NOIP模拟赛

斐波那契

 

 

2017-10-12 NOIP模拟赛

2017-10-12 NOIP模拟赛

2017-10-12 NOIP模拟赛

 

 

2017-10-12 NOIP模拟赛2017-10-12 NOIP模拟赛
/*
    相同颜色的节点与父亲节点的差相等,且是一个小于它的最大斐波那契数 
    所以降两个点同时减去小与它的最大斐波那契数,直到两点相等 
*/
#include<cstdio>
const int maxm=3e5+30;
int m;
long long f[59]={1,1};
int main(){
    freopen("fibonacci.in","r",stdin);freopen("fibonacci.out","w",stdout);
    for(int i=2;i<=58;i++) f[i]=f[i-1]+f[i-2];
    scanf("%d",&m);
    long long a,b;
    while(m--){
        scanf("%lld%lld",&a,&b);
        for(int i=58;a!=b;i--){
            if(a>f[i]) a-=f[i];
            if(b>f[i]) b-=f[i];
        }
        printf("%lld\n",a);
    }
    return 0;
} 
100分

 

数颜色

2017-10-12 NOIP模拟赛

2017-10-12 NOIP模拟赛

2017-10-12 NOIP模拟赛

 

2017-10-12 NOIP模拟赛2017-10-12 NOIP模拟赛
#include<iostream>
#include<cstdio>
#define maxn 300010
using namespace std;
int n,m,a[maxn],sum[maxn],pos[maxn],s[1001][1001],mx;
bool flag1,flag2;
void work2(){
    int op,l,r,x;
    while(m--){
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d%d",&l,&r,&x);
            if(pos[x]>r||pos[x]<l)putchar('0');
            else putchar('1');
            putchar('\n');
        }
        else {
            scanf("%d",&x);
            swap(a[x],a[x+1]);
            swap(pos[a[x]],pos[a[x+1]]);
        }
    }
}
void work(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=mx;j++){
            if(j==a[i])s[i][j]=s[i-1][j]+1;
            else s[i][j]=s[i-1][j];
        }
    }
    int op,l,r,x;
    for(int i=1;i<=m;i++){
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d%d",&l,&r,&x);
            int cnt=s[r][x]-s[l-1][x];
            printf("%d\n",cnt);
        }
        else {
            scanf("%d",&x);
            s[x][a[x]]--;
            s[x][a[x+1]]++;
        }
    }
}
int main(){
    //freopen("Cola.txt","r",stdin);
    freopen("color.in","r",stdin);freopen("color.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        mx=max(mx,a[i]);
        sum[a[i]]++;
        if(sum[a[i]]>1)flag2=1;
        pos[a[i]]=i;
    }
    if(!flag2){//所有兔子亚瑟都不相同 
        work2();
        return 0;
    }
    if(n<=1000){work();return 0;}
    int op,l,r,x;
    for(int i=1;i<=m;i++){
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d%d",&l,&r,&x);
            int w=r-l+1;
            if(w<=n-w){
                int cnt=0;
                for(int j=l;j<=r;j++)if(a[j]==x)cnt++;
                printf("%d\n",cnt);
                continue;
            }
            else {
                int cnt=0;
                for(int j=1;j<=l;j++)if(a[j]==x)cnt++;
                for(int j=r+1;j<=n;j++)if(a[j]==x)cnt++;
                cnt=sum[x]-cnt;
                printf("%d\n",cnt);
            }
        }
        else {
            scanf("%d",&x);
            swap(a[x],a[x+1]);
        }
    }
    return 0;
}
30分 暴力
2017-10-12 NOIP模拟赛2017-10-12 NOIP模拟赛
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define maxn 300010
using namespace std;
vector<int>a[maxn]; 
int n,m,l,r,x;
int pos[maxn];
int main(){
    freopen("color.in","r",stdin);freopen("color.out","w",stdout);
    //freopen("Cola.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&pos[i]),a[pos[i]].push_back(i);
    for(int i=1;i<=300000;i++)sort(a[i].begin(),a[i].end());
    for(int i=1;i<=m;i++){
        int opt;scanf("%d",&opt);
        if(opt==1){
            scanf("%d%d%d",&l,&r,&x);
            int ll=0,rr=a[x].size()-1,ans=-1,mid;
            while(ll<=rr){
                mid=(ll+rr)>>1;
                if(a[x][mid]>=l)ans=mid,rr=mid-1;
                else ll=mid+1;
            }
            if(ans==-1){printf("0\n");continue;}
            ll=0,rr=a[x].size()-1;int ans2=-1;
            while(ll<=rr){
                int mid=(ll+rr)>>1;
                if(a[x][mid]<=r)ans2=mid,ll=mid+1;
                else rr=mid-1;
            }
            if(ans2==-1){printf("0\n");continue;}
            else printf("%d\n",ans2-ans+1);
        }
        else {
            scanf("%d",&x);
            if(pos[x]==pos[x+1])continue;
            else {
                a[pos[x]][lower_bound(a[pos[x]].begin(),a[pos[x]].end(),x)-a[pos[x]].begin()]++;
                a[pos[x+1]][lower_bound(a[pos[x+1]].begin(),a[pos[x+1]].end(),x+1)-a[pos[x+1]].begin()]--;
                swap(pos[x],pos[x+1]);
            }
        }
    }
    return 0;
}
100分 动态数组+二分答案

 

 

分组

2017-10-12 NOIP模拟赛

2017-10-12 NOIP模拟赛

2017-10-12 NOIP模拟赛

2017-10-12 NOIP模拟赛2017-10-12 NOIP模拟赛
#include<iostream>
#include<cstdio>
#include<cmath>
#define maxn 131073
using namespace std;
int n,k,a[maxn],q[maxn],ans=-1,cnt,pp[maxn],numm,mid;
bool flag;
bool no(int w){
    int ww=sqrt(w);
    if(w==ww*ww)return 1;
    return 0;
}
void dfs(int zu,int pos){
    if(flag)return;
    if(pos==n+1&&zu<=mid){
        flag=1;
        return;
    }
    int num=numm;
    int p[100];
    for(int i=1;i<=numm;i++)p[i]=pp[i];
    if(zu<mid&&pos!=1){
        numm=0;
        pp[++numm]=pos;
        q[zu]=pos-1;
        dfs(zu+1,pos+1);
        if(flag)return;
    }
    bool ok=1;
    for(int i=1;i<=num;i++)
        if(no(a[pos]+a[p[i]])){
            ok=0;
            break;
        }
    
    if(ok==1){
        numm=num;for(int i=1;i<=numm;i++)pp[i]=p[i];
        numm=numm+1;
        pp[numm]=pos;
        dfs(zu,pos+1);
        if(flag)return;
    }
    if(flag)return;
    
}
bool check(){
    flag=0;numm=0;
    dfs(1,1);
    if(flag)return 1;
    return 0;
}
int main(){
    //freopen("Cola.txt","r",stdin);
    freopen("division.in","r",stdin);freopen("division.out","w",stdout);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    if(k==1){
        int l=1,r=n;
        while(l<=r){
            mid=(l+r)>>1;
            if(check())ans=mid,r=mid-1;
            else l=mid+1;
        }
        if(ans!=-1){
            printf("%d\n",ans);
            for(int i=1;i<ans;i++)printf("%d\n",q[i]);
            return 0;
        }
        return 0;
    }
    printf("1\n\n");
    return 0;
}
12分 暴力
2017-10-12 NOIP模拟赛2017-10-12 NOIP模拟赛
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 131073
using namespace std;
int n,m,k;
int a[maxn],b[maxn],f[maxn<<1];
bool vis[maxn],dvis[maxn],issqr[maxn<<1];
int find(int x){
    return f[x]>0?(f[x]=find(f[x])):x;
}
void merge(int u,int v){
    u=find(u),v=find(v);
    if(u!=v){
        if(f[u]>f[v])swap(u,v);
        f[u]+=f[v];f[v]=u;
    }
}
bool check(int u,int v){
    int r1=find(u),r2=find(u+maxn);
    int s1=find(v),s2=find(v+maxn);
    if(r1==s1||r2==s2)return 1;
    merge(r1,s2);merge(r2,s1);
    return 0;
}
void work1(){
    for(int i=n,j=n;i;){
        for(bool flag=1;j;j--){
            for(int k=1;k*k-a[j]<maxn;k++){
                if(k*k-a[j]<=0)continue;
                if(vis[k*k-a[j]]){flag=0;break;}
            }
            if(!flag)break;
            vis[a[j]]=1;
        }
        if(!j)break;b[++m]=j;
        for(;i>j;i--)vis[a[i]]=0;
    }
}
void work2(){
    memset(f,-1,sizeof(f));
    for(int i=1;i*i<2*maxn;i++)issqr[i*i]=1;
    for(int i=n,j=n;i;){
        for(bool flag=1;j;j--){
            if(vis[a[j]]){
                if(issqr[a[j]+a[j]]){
                    if(dvis[a[j]])break;
                    for(int k=1;k*k-a[j]<maxn;k++){
                        if(k*k-a[j]<=0)continue;
                        if(vis[k*k-a[j]]&&k*k!=a[j]*2){flag=0;break;}
                    }
                    if(!flag)break;dvis[a[j]]=1;
                }
            }
            else {
                for(int k=1;k*k-a[j]<maxn;k++){
                    if(k*k-a[j]<=0)continue;
                    if(vis[k*k-a[j]]){
                        if(check(k*k-a[j],a[j])){flag=0;break;}
                    }
                }
                if(!flag)break;vis[a[j]]=1;
            }
        }
        if(!j)break;b[++m]=j;
        for(;i>j;i--)f[a[i]]=f[a[i]+maxn]=-1,vis[a[i]]=0,dvis[a[i]]=0;
    }
}
int main(){
    //freopen("Cola.txt","r",stdin);
    freopen("division.in","r",stdin);freopen("division.out","w",stdout);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    if(k==1)work1();
    else work2();
    printf("%d\n",m+1);
    for(int i=m;i;i--)printf("%d ",b[i]);
    putchar('\n');
    return 0;
}
100分 并查集

 

2017-10-12 NOIP模拟赛2017-10-12 NOIP模拟赛
/*
T1考场上没想出正解来,就打了个暴力,暴力挂了,得到正解发现这题是这么的简单
T2,T3直接练暴力了,T3调了将近一个半小时
这次考试成绩不理想,主要是败在T1了,noip的T1应该是一眼题,这个T1不是
再加上心态不好
考场上总还是不免有一些题想不出正解,但是暴力出错就太可惜了,以后暴力还是要努力写的,尽量不要出错误(不要不屑于手造数据),希望以后能避免类似今天T1的错误
Noip前每次模拟考试出现的失误都有可能反映在正式考试中
切记切记,下不为例

*/
小结