NOIP2008提高组题解

(D1T1) 笨小猴 ((OK))

(D1T2) 火柴棒等式 ((OK))

(D1T3) 传纸条 ((OK))

(D1T4) 双栈排序 ((OK))

唯一一道蓝(难)题不久之前考过,所以做得特别快.

(T1)超级简单的字符串模拟题,加个(O(sqrt n))的判断素数即可.

#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 sum[30];
inline bool check(int x){
	if(x==0||x==1)return 0;
	if(x==2||x==3)return 1;
	for(int i=2;i*i<=x;++i)
		if(x%i==0)return 0;
	return 1;
}
int main(){
	scanf("%s",s+1);int n=strlen(s+1);
	for(int i=1;i<=n;++i)++sum[s[i]-'a'+1];
	int maxn=0,minn=1<<30;
	for(int i=1;i<=26;++i){
		if(!sum[i])continue;
		if(sum[i]>maxn)maxn=sum[i];
		if(sum[i]<minn)minn=sum[i];
	}
	int ans=maxn-minn;
	if(check(ans)){
		puts("Lucky Word");
		printf("%d
",ans);
		return 0;
	}
	puts("No Answer");puts("0");
    return 0;
}

(T2)直接枚举(a,b)得到(c),然后暴力计算需要多少根火柴棒即可.(a,b)的枚举下界是(0),枚举上界的话,随便搞个稍微大一点的值即可,默认时间复杂度是(O(n^2))的,所以(1000)足够了.

#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 bj[1005][1005];
int a[10]={6,2,5,5,4,5,6,3,7,6};
inline int calc(int x){
	if(!x)return 6;
	int cnt=0;
	while(x){
		cnt+=a[x%10];
		x/=10;
	}
	return cnt;
}
int main(){
	int n=read()-4,ans=0,now,hehe;
	for(int i=0;i<=1000;++i){
		now=n;if(now-calc(i)<=0)continue;now-=calc(i);
		for(int j=0;j<=1000;++j){
			if(bj[i][j])continue;hehe=now;
			if(hehe-calc(j)<=0)continue;hehe-=calc(j);
			hehe-=calc(i+j);if(hehe!=0)continue;
			if(!bj[i][j])++ans,bj[i][j]=1;
		}
	}
	printf("%d
",ans);
    return 0;
}

(T3)做过好多次了,直接把两次都看作从((1,1))((n,m))的,设(f[i][j][k][l])表示第一轮走到了((i,j)),第二轮走到了((k,l))时的最大得分,然后(n^4)枚举(i,j,k,l),直接转移即可,如果(i==k)(j==l),代表这个点的得分算重了,减掉即可.

#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=51;
int f[N][N][N][N],a[N][N];
int main(){
	int n=read(),m=read();
	for(int i=1;i<=n;++i)for(int j=1;j<=m;j++)a[i][j]=read();
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			for(int k=1;k<=n;++k){
				for(int l=1;l<=m;++l){
					f[i][j][k][l]=max(f[i-1][j][k-1][l],max(f[i-1][j][k][l-1],max(f[i][j-1][k-1][l],f[i][j-1][k][l-1])))+a[i][j]+a[k][l];
					if(i==k&&j==l)f[i][j][k][l]-=a[i][j];
				}
			}
		}
	}
	printf("%d
",f[n][m][n][m]);
    return 0;
}

(T4)博客

原文地址:https://www.cnblogs.com/PPXppx/p/11801953.html