P2327 [SCOI2005]扫雷

输入输出格式

输入格式:

 

第一行为N,第二行有N个数,依次为第二列的格子中的数。(1<= N <= 10000)

 

输出格式:

 

一个数,即第一列中雷的摆放方案数。

 

输入输出样例

输入样例#1:
2
1  1
输出样例#1:2


题目大意 有两列 右边的列的数字表示这个格子的八个方向的雷的数量 求雷位置的方案数。

题解
递推
看错题了 写了个错的dfs水了10分...我还是放一下吧...

每个格子有两个状态 有雷和没有雷 然后当第一个格子放雷时,和不放雷时,进行判断一下
行不行 所以方案数只有0、1、2种,注意最后判断n+1个格子有没有雷

代码
10分错的dfs //
#include<iostream>
#include<cstdio>
using namespace std;

int ans,n,minn=0x7ffff,cnt[10005];                                                                                                                 
bool ok(){
    for(int i=1;i<=n;i++)if(cnt[i])return 0;
    return 1;
}

bool check(int k){
    if((k==1||k==2)&&n>=3)
      if(cnt[1]&&cnt[2]&&cnt[3])return 1;
        else return 0;
    if((k==n||k==n-1)&&n>=3)
      if(cnt[n]&&cnt[n-1]&&cnt[n-2])return 1;
       else return 0;
    if(n<3)for(int i=1;i<=n;i++)if(!cnt[i])return 0;
    else return 1;
        for(int i=k;i<=k+2;i++)if(!cnt[i])return 0;
        for(int j=k;j>=k-2;j--)if(!cnt[j])return 0;
        return 1;
}

void put(int k){
    if(n<=3)for(int i=1;i<=n;i++)cnt[i]--;
    else if(k<=2)cnt[1]--,cnt[2]--,cnt[3]--;
    else {
        for(int i=k;i<=k+2;i++)cnt[i]--;
        for(int i=k-1;i>=k-2;i--)cnt[i]--;
    }
}

void back(int k){
    if(n<=3)for(int i=1;i<=n;i++)cnt[i]++;
    else if(k<=2)cnt[1]++,cnt[2]++,cnt[3]++;
    else {
        for(int i=k;i<=k+2;i++)cnt[i]++;
        for(int i=k-1;i>=k-2;i--)cnt[i]++;
    }
}

void dfs(int k){
    if(k==n+1){
        if(ok())ans++;
        return ;
    }
    if(check(k)){
        put(k);
        dfs(k+1);
        back(k);
    }
    dfs(k+1);
    return;                                          
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&cnt[i]),minn=min(minn,cnt[i]);
    if(n<=3&&minn==0){
        printf("0\n");
        return 0;
    }
    dfs(1);
    printf("%d\n",ans);
    return 0;
}

 

正解

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans,a[10005],b[10003];
bool ok(){
    for(int i=2;i<=n;i++){
        b[i]=a[i-1]-b[i-1]-b[i-2];
        if(b[i]!=0&&b[i]!=1)return 0;
        if(i==n&&(a[n]-b[n]-b[n-1])!=0)return 0;
    }
    return 1;
    
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    b[1]=1;
    if(ok())ans++;
    b[1]=0;
    if(ok())ans++;
    printf("%d",ans);
    return 0;
}

今天下午晕呼呼的(~ o ~)~zZ 效率低真讨厌╭(╯^╰)╮

 

 

posted @ 2017-09-05 15:31  ANhour  阅读(263)  评论(0编辑  收藏  举报