zoukankan      html  css  js  c++  java
  • NOIP2007提高组题解

    (D1T1) 统计数字 ((OK))

    (D1T2) 字符串的展开 ((OK))

    (D1T3) 矩阵取数游戏 ((OK))

    (D1T4) 树网的核 ((OK))

    就最后一道对着样例调了半个小时,其它题都挺容易的.

    (T1)就把序列sort排序然后每个数判断有多少个相同的即可.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    int a[200005];
    int main(){
    	int n=read();for(int i=1;i<=n;++i)a[i]=read();
    	sort(a+1,a+n+1);int i=1;
    	while(i<=n){
    		int sum=1;
    		while(a[i+1]==a[i])++i,++sum;
    		printf("%d %d
    ",a[i],sum);
    		++i;
    	}
        return 0;
    }
    
    

    (T2)字符串+大模拟.昨晚打了半个多小时,(WA)了三个点,然后今天早上又过来面向数据编程对着数据调了一会,有一种恶心的情况没有考虑到.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    char s[105];int bj[105];
    char xx[30]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    char dx[30]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
    char sz[10]={'0','1','2','3','4','5','6','7','8','9'};
    int main(){
    	int p1,p2,p3;scanf("%d%d%d",&p1,&p2,&p3);
    	scanf("%s",s+1);int n=strlen(s+1);
    	for(int i=1;i<=n;++i){
    		if(s[i]=='-'){
    			if(i==1||s[i-1]=='-'){
    				printf("-");
    				continue;
    			}
    			--i;
    		}//刚开始没考虑这一位就是'-'的情况
    		if(s[i+1]!='-'){
    			if(!bj[i])bj[i]=1,printf("%c",s[i]);
    			continue;
    		}
    		if(s[i]>='a'&&s[i]<='z'){
    			if((s[i+2]<=s[i])||(s[i+2]>='0'&&s[i+2]<='9')){
    				if(!bj[i])printf("%c",s[i]),bj[i]=1;
    				if(!bj[i+2])printf("-%c",s[i+2]),bj[i+2]=1;
    				i+=2;continue;
    			}
    			if(s[i+2]==s[i]+1){
    				if(!bj[i])printf("%c",s[i]),bj[i]=1;
    				if(!bj[i+2])printf("%c",s[i+2]),bj[i+2]=1;
    				i+=2;continue;
    			}
    			if(!bj[i])printf("%c",s[i]),bj[i]=1;
    			if(p3==1){
    				if(p1==1){
    					for(int k=s[i]+1;k<=s[i+2]-1;++k)
    						for(int j=1;j<=p2;++j)printf("%c",xx[k-'a']);
    				}
    				if(p1==2){
    					for(int k=s[i]+1;k<=s[i+2]-1;++k)
    						for(int j=1;j<=p2;++j)printf("%c",dx[k-'a']);
    				}
    				if(p1==3){
    					for(int k=s[i]+1;k<=s[i+2]-1;++k)
    						for(int j=1;j<=p2;++j)printf("*");
    				}
    			}
    			else{
    				if(p1==1){
    					for(int k=s[i+2]-1;k>=s[i]+1;--k)
    						for(int j=1;j<=p2;++j)printf("%c",xx[k-'a']);
    				}
    				if(p1==2){
    					for(int k=s[i+2]-1;k>=s[i]+1;--k)
    						for(int j=1;j<=p2;++j)printf("%c",dx[k-'a']);
    				}
    				if(p1==3){
    					for(int k=s[i+2]-1;k>=s[i]+1;--k)
    						for(int j=1;j<=p2;++j)printf("*");
    				}
    			}
    			if(!bj[i+2])printf("%c",s[i+2]),bj[i+2]=1;
    			i+=2;continue;
    		}
    		if(s[i]>='0'&&s[i]<='9'){
    			if((s[i+2]<=s[i])||(s[i+2]>='a'&&s[i+2]<='z')){
    				if(!bj[i])printf("%c",s[i]),bj[i]=1;
    				if(!bj[i+2])printf("-%c",s[i+2]),bj[i+2]=1;
    				i+=2;continue;
    			}
    			if(s[i+2]==s[i]+1){
    				if(!bj[i])printf("%c",s[i]),bj[i]=1;
    				if(!bj[i+2])printf("%c",s[i+2]),bj[i+2]=1;
    				i+=2;continue;
    			}
    			if(!bj[i])printf("%c",s[i]),bj[i]=1;
    			if(p3==1){
    				if(p1==1){
    					for(int k=s[i]+1;k<=s[i+2]-1;++k)
    						for(int j=1;j<=p2;++j)printf("%c",sz[k-'0']);
    				}
    				if(p1==2){
    					for(int k=s[i]+1;i<=s[i+2]-1;++k)
    						for(int j=1;j<=p2;++j)printf("%c",sz[k-'0']);
    				}
    				if(p1==3){
    					for(int k=s[i]+1;i<=s[i+2]-1;++k)
    						for(int j=1;j<=p2;++j)printf("*");
    				}
    			}
    			else{
    				if(p1==1){
    					for(int k=s[i+2]-1;k>=s[i]+1;--k)
    						for(int j=1;j<=p2;++j)printf("%c",sz[k-'0']);
    				}
    				if(p1==2){
    					for(int k=s[i+2]-1;k>=s[i]+1;--k)
    						for(int j=1;j<=p2;++j)printf("%c",sz[k-'0']);
    				}
    				if(p1==3){
    					for(int k=s[i+2]-1;k>=s[i]+1;--k)
    						for(int j=1;j<=p2;++j)printf("*");
    				}
    			}
    			if(!bj[i+2])printf("%c",s[i+2]),bj[i+2]=1;
    			i+=2;continue;
    		}
    	}printf("
    ");
        return 0;
    }
    
    

    (T3)每一行都是独立的,所以可以分开来做,每一次只能取首尾,所以当前剩下的没取的一定是中间连续的一段,有点类似于区间(DP),设(f[j][k])表示第i行取完了区间([j,k])时的最大得分,则(f[j][k]=max(f[j+1][k]+val[i][j]*2^{m-(k-j)},f[j][k-1]+val[i][k]*2^{m-(k-j)})).

    所以初始化就是(f[j][j]=val[i][j]*2^m)

    不想写高精,那就用__(int128),毒奶一口(CSP)不考高精.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=85;
    int n,m,a[N];
    __int128 ans,Base[N],f[N][N];
    inline void print(__int128 x){
        if(x<0){
            putchar('-');
            x=-x;
        }
        if(x>9)print(x/10);
        putchar(x%10+'0');
    }
    int main(){
    	n=read(),m=read();
    	Base[0]=1;for(int i=1;i<=m;++i)Base[i]=Base[i-1]<<1;
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j)a[j]=read();
    		memset(f,0,sizeof(f));
    		for(int j=1;j<=m;++j)f[j][j]=Base[m]*a[j];
    		for(int len=2;len<=m;++len){
    			for(int j=1;j+len-1<=m;++j){
    				int k=j+len-1;
    				f[j][k]=max(f[j+1][k]+a[j]*Base[m-(k-j)],f[j][k-1]+a[k]*Base[m-(k-j)]);
    			}
    		}
    		ans+=f[1][m];
    	}
    	print(ans);printf("
    ");
        return 0;
    }
    
    

    (T4)这道题不久前学树的直径的时候是蓝书上的例题,依稀记得蓝书上讲了好多种方法,今天再做我一眼想到的就是一个比较辣鸡的算法.

    预处理出树的直径((dfs)求树的直径可以记录直径上的各种信息),然后枚举树网的核的一个端点,另一个端点能多远就多远(这样一定是最优的),然后这一段就是当前枚举出的树网的核,从核开始(dfs)求出非核上的点到核的最大距离,每次枚举的最大值的最小值就是答案.

    之前写的博客写了两种方法.博客

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=305;
    int n,s,ans=1<<30;
    int d[N][N],dis[N],pre[N],bj[N];
    int tot,head[N],nxt[N<<1],to[N<<1],w[N<<1];
    queue<int>q;
    inline void add(int a,int b,int c){nxt[++tot]=head[a];head[a]=tot;to[tot]=b;w[tot]=c;}
    inline void dfs(int u,int fa){
    	for(int i=head[u];i;i=nxt[i]){
    		int v=to[i];if(v==fa)continue;
    		dis[v]=dis[u]+w[i];pre[v]=u;dfs(v,u);
    	}
    }
    inline void DFS(int u,int fa){
    	for(int i=head[u];i;i=nxt[i]){
    		int v=to[i];if(v==fa||bj[v])continue;
    		dis[v]=dis[u]+w[i];DFS(v,u);
    	}
    }
    int main(){
    	n=read();s=read();
    	for(int i=1;i<n;++i){
    		int a=read(),b=read(),c=read();
    		add(a,b,c);add(b,a,c);d[a][b]=d[b][a]=c;
    	}
    	int pos1=0,pos2=0,maxn=0;dfs(1,0);
    	for(int i=1;i<=n;++i)if(dis[i]>maxn)maxn=dis[i],pos1=i;
    	dis[pos1]=0;dfs(pos1,0);maxn=0;for(int i=1;i<=n;++i)if(dis[i]>maxn)maxn=dis[i],pos2=i;
    	pre[pos1]=0;
    	for(int rt=pos2;rt!=0;rt=pre[rt]){
    		memset(bj,0,sizeof(bj));
    		int now=0,j=rt;q.push(j);bj[j]=1;
    		while(pre[j]&&now+d[j][pre[j]]<=s){
    			now+=d[j][pre[j]];bj[pre[j]]=1;q.push(pre[j]);
    			j=pre[j];
    		}
    		while(q.size()){
    			int x=q.front();q.pop();
    			dis[x]=0;DFS(x,0);
    		}
    		int cnt=0;
    		for(int i=1;i<=n;++i)cnt=max(cnt,dis[i]);
    		ans=min(ans,cnt);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Alpha 冲刺报告6
    课堂小测(同学录)
    Alpha 冲刺报告5
    alphe4
    Alpha 冲刺报告3
    软件工程实践2017第二次作业
    软件工程实践2017第一次作业
    面向对象程序设计 第六次作业
    1025 反转链表(待完善)
    面向对象程序设计 第五次作业
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11803115.html
Copyright © 2011-2022 走看看