NOIP2017普及组题

提高组死亡选手来AK普及(耗时两天)。

T1

#include<bits/stdc++.h>
using namespace std;
int A,B,C;
int main()
{
    cin>>A>>B>>C;
    cout<<(A*2+B*3+C*5)/10<<"\n";
    return 0;
}

T2

无脑找答案

#include<bits/stdc++.h>
using namespace std;
int N,Q,a[1050],b,x,t;
int main()
{
    cin>>N>>Q;
    for(int i=1;i<=N;i++)cin>>a[i];
    sort(a+1,a+N+1);
    while(Q--){
        cin>>b>>x;
        t=pow(10,b);
        int ans=-1;
        for(int i=1;i<=N;i++)
            if(a[i]%t==x){
                ans=a[i];
                break;
            }
        cout<<ans<<"\n";
    }
    return 0;
}    

T3

连边,取一个有颜色的块,

1.四周有颜色的块 相同连0 不同连1

2.与他距离为2的块 相同连2 不同连3

3.这一点忘了就少一半分,四周没有颜色的块要连2,否则有好多都会误判成“-1”

然后跑SPFA,没了

                        #include<bits/stdc++.h>
using namespace std;
int N,M,color[105][105],last[10005],cnt,
x,y,z,d1[4]={1,-1,0,0},d2[4]={0,0,-1,1},dis[10005];
int D1[8]={0,0,2,-2,1,1,-1,-1},D2[8]={2,-2,0,0,1,-1,1,-1};
bool vis[10005];
queue <int> q;
struct Edge{
    int other,pre,val;
}e[100005];
void connect(int x,int y,int z){
    e[++cnt]=(Edge){y,last[x],z};
    last[x]=cnt;
}
int main()
{
    cin>>M>>N;
    for(int i=1;i<=N;i++){
        cin>>x>>y>>z;
        color[x][y]=z+1;        //0 nah 1 red 2 yellow
    }
    for(int i=1;i<=M;i++)
        for(int j=1;j<=M;j++)
            if(color[i][j]){
                for(int k=0;k<=3;k++){
                    int tx=i+d1[k],ty=j+d2[k];
                    if(tx<1||tx>M||ty<1||ty>M)continue;
                //    printf("[%d,%d]\n",tx,ty);
                    if(color[tx][ty]){
                        int v=1;
                        if(color[tx][ty]==color[i][j])v=0;
                //        printf("(%d,%d)->(%d,%d)cost=%d\n",i,j,tx,ty,v);
                        connect((i-1)*M+j,(tx-1)*M+ty,v);                    
                    }
                    else {
                        connect((i-1)*M+j,(tx-1)*M+ty,2);//    printf("z(%d,%d)->(%d,%d)cost=%d\n",i,j,tx,ty,2);
                    }
                }
                for(int l=0;l<=7;l++){
                    int lx=i+D1[l],ly=j+D2[l];
                    if(lx<1&&lx>M&&ly<1&&ly>M)continue;
                    if(lx==i&&ly==j)continue;
                    if(!color[lx][ly])continue;                                
                    int v=3;
                    if(color[i][j]==color[lx][ly])v=2;
                //    printf("(%d,%d)->(%d,%d)cost=%d\n",i,j,lx,ly,v);
                    connect((i-1)*M+j,(lx-1)*M+ly,v);
                }
            }    
    memset(dis,0x3f,sizeof dis);
    vis[1]=1,dis[1]=0;
    q.push(1);
    while(!q.empty()){
        int u=q.front();
        vis[u]=0,q.pop();
        for(int i=last[u];i;i=e[i].pre){
            int v=e[i].other;
            if(dis[v]>dis[u]+e[i].val){
                dis[v]=dis[u]+e[i].val;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(dis[M*M]==dis[0])puts("-1");
    else printf("%d\n",dis[M*M]);
    return 0;
}
                    

T4

二分答案+DP

朴素DP N^2  我们很容易的看出可以拿单调队列优化

#include<bits/stdc++.h>
#define MAXN 500005
#define INF 0x7f7f7f7f
using namespace std;
int read(){
    int x=0,t=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')t=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*t;
}
int N,D,K,x[MAXN],c[MAXN],f[MAXN];
pair <int,int> q[MAXN]; 
bool Judge(int L){
    memset(f,0,sizeof f);
    int a=D-L,b=D+L,head=0,tail=-1,cur=0;
    if(a<=0)a=1;
    for(int i=1;i<=N;i++){
        for(cur;cur<i&&x[cur]<=x[i]-a;cur++){
            while(head<=tail&&q[tail].first<f[cur])tail--;
            if(f[cur]<=-INF)continue;
            q[++tail].first=f[cur],q[tail].second=x[cur];
        }
        while(head<=tail&&x[i]-q[head].second>b)head++;
        if(head<=tail)f[i]=q[head].first+c[i];
        else f[i]=-INF;
        if(f[i]>=K)return 1;    
    }
    return 0;
}
int main()
{
    N=read(),D=read(),K=read();
    for(int i=1;i<=N;i++)x[i]=read(),c[i]=read();
    if(!Judge(x[N]))puts("-1");
    else{
        int l=0,r=x[N];
        while(l<r){
            int mid=l+r>>1;
            if(Judge(mid))r=mid;
            else l=mid+1;
        }
        printf("%d\n",l);
    }
    return 0;
} 

 

posted @ 2017-11-26 19:12  Elfish?  阅读(260)  评论(0编辑  收藏  举报