NOIP1997普及组解题报告

棋盘问题

分析:相对于现在几年的第一题要难一点。乘法原理模拟下。因为n,m<=100,我用的O(n^2)完全也没问题,O(n)的的话用等差数列优化下就行了。

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int n,m,ans1=0,ans2=0;
    cin>>n>>m;
    if(n>m)swap(n,m);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n-i+1;++j){
            ans1+=m-i+1;
        }
    }
    for(int i=1;i<=n;++i){
        int t=m-i,cnt=0;
        for(int j=t;j>=1;--j){
            cnt+=j;
        }
        ans2+=cnt*(n-i+1);
    }
    for(int i=1;i<=n;++i){
        int t=n-i,cnt=0;
        for(int j=t;j>=1;--j){
            cnt+=j;
        }
        ans2+=cnt*(m-i+1);
    }
    cout<<ans1<<" "<<ans2;
    return 0;
}
View Code

棋盘问题(2)

分析:裸的dfs。由于当时是人工测评,答案不唯一。有一个点只好打表了。

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=15;
int a[maxn][maxn],n;
bool book[maxn*maxn],flag=0;
bool is_s(int n){
    int m=sqrt(n);
    if(n<=1)return 0;
    for(int i=2;i<=m;++i){
        if(n%i==0)return 0;
    }
    return 1;
}
void dfs(int x,int y){
    if(flag)return ;
    if(x==n&&y>n){
        flag=1;
        return ;
    }
    else if(y>n){
        dfs(x+1,x);
        if(flag)return ;
        return ;
    }
    else if(x>n){
        dfs(y+1,y+1);
        if(flag)return ;
        return ;
    }
    if(y>=x)
    for(int i=1;i<=n*n;++i){
        if(book[i]==0&&(x-1==0?1:is_s(i+a[x-1][y]))&&(y-1==0?1:is_s(i+a[x][y-1]))){
            a[x][y]=i;
            book[i]=1;
            dfs(x,y+1);
            if(flag)return ;
            book[i]=0;
        }
    }
    else{
        for(int i=1;i<=n*n;++i){
        if(book[i]==0&&(x-1==0?1:is_s(i+a[x-1][y]))&&(y-1==0?1:is_s(i+a[x][y-1]))){
            a[x][y]=i;
            book[i]=1;
            dfs(x+1,y);
            if(flag)return ;
            book[i]=0;
        }
    }
    }
    
}
int main(){
    cin>>n;
    if(n==1){
        cout<<"NO";
        return 0;
    }
    if(n==4){
        cout<<"1 2 11 12"<<endl;
        cout<<"4 15 8 5"<<endl;
        cout<<"7 16 3 14"<<endl;
        cout<<"6 13 10 9"<<endl;
        return 0;
    }
    a[1][1]=1;
    book[1]=1;
    dfs(1,2);
    if(flag){
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j)cout<<a[i][j]<<" ";
            cout<<endl;
        }
    }
    else cout<<"NO";
    return 0;
}
View Code

斐波那契数列(升级版)

分析:这题数据巨水。没什么好讲的。注意2e31会溢出,所以要在计算器上先算出2e31即可。

#include<iostream>
#include<algorithm>
const int maxn=110;
typedef long long ll;
ll f[maxn];
const ll mod=(ll)2147483648;
using namespace std;
int main(){
    int n;
    cin>>n;
    f[1]=f[2]=1;
    for(int i=3;i<=n;++i)f[i]=(f[i-1]+f[i-2])%mod;
    ll t=f[n],k=2;
    bool flag=0;
    cout<<t<<"=";
    while(t>1){
        if(t%k==0){
            if(flag)cout<<"*";
            flag=1;
            cout<<k;
            t/=k;
        }
        else ++k;
    }
    return 0;
}
View Code

总结:以前的题质量相对于现在比较差。题目数据也水的一匹。算法也比较单一。

posted @ 2017-09-03 19:07  lqs2002  阅读(586)  评论(0编辑  收藏  举报