Menagerie 水题 递推

题目:

Snuke, who loves animals, built a zoo.

There are N animals in this zoo. They are conveniently numbered 1 through N, and arranged in a circle. The animal numbered i(2≤iN−1) is adjacent to the animals numbered i−1 and i+1. Also, the animal numbered 1 is adjacent to the animals numbered 2 and N, and the animal numbered N is adjacent to the animals numbered N−1 and 1.

There are two kinds of animals in this zoo: honest sheep that only speak the truth, and lying wolves that only tell lies.

Snuke cannot tell the difference between these two species, and asked each animal the following question: "Are your neighbors of the same species?" The animal numbered i answered si. Here, if si is o, the animal said that the two neighboring animals are of the same species, and if si is x, the animal said that the two neighboring animals are of different species.

More formally, a sheep answered o if the two neighboring animals are both sheep or both wolves, and answered x otherwise. Similarly, a wolf answered x if the two neighboring animals are both sheep or both wolves, and answered o otherwise.

Snuke is wondering whether there is a valid assignment of species to the animals that is consistent with these responses. If there is such an assignment, show one such assignment. Otherwise, print -1.

约束条件:

  • 3≤N≤105
  • s is a string of length N consisting of o and x.

输入:

The input is given from Standard Input in the following format:

N
s

输出:

If there does not exist an valid assignment that is consistent with s, print -1. Otherwise, print an string t in the following format. The output is considered correct if the assignment described by t is consistent with s.

  • t is a string of length N consisting of S and W.
  • If ti is S, it indicates that the animal numbered i is a sheep. If ti is W, it indicates that the animal numbered i is a wolf.

样例输入1:

6
ooxoox

样例输出:

SSSWWS

样例输入2:

3
oox

样例输出:-1

样例输入3:

10
oxooxoxoox

样例输出:

SSWWSSSWWS

题意:有两种动物,羊和狼,羊是说真话的,狼是说假话的。当羊说‘o’时,说明他的两边动物类型是相同的,说'x'时,说明他的两边动物类型是不同的。当狼说'o'时,说明他的两边动物类型是不同的,说'x'时,说明他的两边动物类型是相同的。给你一串关于ox的字符串,问是否有那么一个动物序列满足这个字符串。如果有,就输出,如果没有,输入-1.

可以用递推的方式,知道前两个的动物类型,可以推出后面的动物类型,然后根据ox字符串判断一下是否满足条件。前两个的组合一共有四个,羊羊、狼狼、羊狼、狼羊。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
int n;
char s[maxn];
int vis[maxn];
int check()//判断条件
{
    for(int i=1;i<=n;i++)
    {
        int l=i-1;
        int r=i+1;
        if(l==0) l=n;//因为是一个圈,所以i-1为0时就是n,i+1为n+1时就是1。
        if(r==n+1)r=1;
        if(vis[i]==1)
        {
            if(s[i]=='o'&&vis[l]!=vis[r])
                return 0;
            if(s[i]=='x'&&vis[l]==vis[r])
                return 0;
        }
        if(vis[i]==2)
        {
            if(s[i]=='o'&&vis[l]==vis[r])
                return 0;
            if(s[i]=='x'&&vis[l]!=vis[r])
                return 0;
        }
    }
    return 1;
}
void init()//递推,根据前两个动物类型和已知的OX字符串推出剩下的动物类型
{
    for(int i=2;i<n;i++)
    {
        if(vis[i]==1)
        {
            if(s[i]=='o') vis[i+1]=vis[i-1];
            else vis[i+1]=(vis[i-1]==1?2:1);
        }
        if(vis[i]==2)
        {
            if(s[i]=='o')vis[i+1]=(vis[i-1]==1?2:1);
            else vis[i+1]=vis[i-1];
        }
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%s",s+1);
    vis[1]=vis[2]=1;//vis[i]==1时是羊,vis[i]==2时是狼
    init();
    if(check())
    {
        for(int i=1;i<=n;i++)
        {
            printf("%c",vis[i]==1?'S':'W');
        }
            printf("\n");
            return 0;
    }
    vis[1]=vis[2]=2;
    init();
    if(check())
    {
        for(int i=1;i<=n;i++)
        {
            printf("%c",vis[i]==1?'S':'W');
        }
        printf("\n");
        return 0;
    }
    vis[1]=1;
    vis[2]=2;
    init();
    if(check())
    {
        for(int i=1;i<=n;i++)
        {
            printf("%c",vis[i]==1?'S':'W');
        }
        printf("\n");
        return 0;
    }
    vis[1]=2;
    vis[2]=1;
    init();
    if(check())
    {
        for(int i=1;i<=n;i++)
        {
            printf("%c",vis[i]==1?'S':'W');
        }
        printf("\n");
        return 0;
    }
    printf("-1\n");
    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值