NOIP2008提高组题解

版权声明:欢迎转载+原文章地址~ https://blog.csdn.net/Hi_KER/article/details/82593731

T1:笨小猴

考察知识:字符串,素数判定

算法难度:X+ 实现难度:X+

分析:

直接输入后安装要求计算就可以了。

#include<cstdio>
bool isprime(int n){
    if(n<=1) return false;
    for(int i=2;i<n;i++) if(n%i==0) return false;
    return true;
}
int a[28],maxn=0,minn=105;
int main(){
    char s[105];scanf("%s",s);
    for(int i=0;s[i]!='\0';i++) a[s[i]-'a']++;
    for(int i=0;i<26;i++) if(a[i])
        maxn=maxn>a[i]?maxn:a[i],minn=minn>a[i]?a[i]:minn;
    printf("%s\n%d",isprime(maxn-minn)?"Lucky Word":"No Answer",isprime(maxn-minn)?maxn-minn:0);
    return 0;
}

T2:火柴棒等式

考察知识:枚举

算法难度:XX+ 实现难度:XX+

分析:

我们先预处理数字在1...999(因为四位数最少火柴1111,有8根,3个数字就会超过24根)的所有整数需要的火柴棒,然后枚举所有的等式就可以了:

for(i=0;i<=999;i++){
	for(j=0;j<=999;j++){
		if(n==num[i]+num[j]+num[i+j]+4) cnt++;
	}
}

注意到数据范围很小我们可以采取打表法。

代码:

#include<iostream>
using namespace std;
int ans[]={0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,8,9,6,9,29,39,38,65,88,128};
int n;
int main(){
    cin>>n;
    cout<<ans[n]<<'\n';
    return 0;
}

T3:传纸条

考察知识:动态规划

算法难度:XXX+ 实现难度:XXX

分析:

想到方法就不难了,我们可以把两次传纸条看做一次,而这一次没一步有两个位置的变化。

定义状态方程:f(i,j,k)表示两个位置,一个在i,一个在j,且走了k步后得到的最大值

状态转移方程:f(i,j,k)=max\begin{Bmatrix} f(i,j,k-1)\\ f(i-1,j,k-1)\\ f(i,j-1,k-1)\\ f(i-1,j-1,k-1) \end{Bmatrix}+a[i][k-i+2]+a[j][k-j+2]

其中两个位置不能相同

边界:f(1,1,0)=0;

代码:

#include<cstdio>
#define Max(var,var_) var=(var)>(var_)?(var):(var_)
#define F(var,L,R) for(int var=L;var<=R;var++)
int n,m,a[55][55],f[52][52][102];
bool chk(int x,int y,int x_,int y_){
    if(x<1||x>m||y<1||y>n) return false;
    if(x_<1||x_>m||y_<1||y_>n) return false;
    if(x==x_&&y==y_) return false;
    return true;
}
int main(){
    scanf("%d%d",&m,&n);
    F(i,1,m) F(j,1,n) scanf("%d",&a[i][j]);
    F(k,1,m+n-2) F(i,1,m) F(j,1,m) {
        int i_=k+2-i,j_=k+2-j;
        if(i_<1||j_<1||i_>n||j_>n||(i==j&&(i!=m||k!=m+n-2))) continue;
        if(chk(i,i_-1,j,j_-1)) Max(f[i][j][k],f[i][j][k-1]);
        if(chk(i-1,i_,j,j_-1)) Max(f[i][j][k],f[i-1][j][k-1]);
        if(chk(i,i_-1,j-1,j_)) Max(f[i][j][k],f[i][j-1][k-1]);
    	if(chk(i-1,i_,j-1,j_)) Max(f[i][j][k],f[i-1][j-1][k-1]);
    	f[i][j][k]+=a[i][i_]+a[j][j_];
    }
    printf("%d\n",f[m][m][m+n-2]);
    return 0;
}

T4:双栈排序

working...

猜你喜欢

转载自blog.csdn.net/Hi_KER/article/details/82593731