P1278 单词游戏

题目描述
Io和Ao在玩一个单词游戏。
他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致。
游戏可以从任何一个单词开始。
任何单词禁止说两遍 ,游戏中只能使用给定词典中含有的单词。
游戏的复杂度定义为游戏中所使用的单词长度总和。
编写程序,求出使用一本给定的词典来玩这个游戏所能达到的游戏最大可能复杂度。
输入格式 输入文件的第一行,表示一个自然数N(1≤N≤16),N表示一本字典中包含的单词数量以下的每一行包含字典中的一个单词,每一个单词是由字母A、E、I、O和U组成的一个字符串,每个单词的长度将小于等于100,所有的单词是不一样的。
输出格式 输出文件仅有一行,表示该游戏的最大可能复杂度。
输入输出样例
输入:
5
IOO
IUUO
AI
OIOOI
AOOI
输出:
16

一开始我用的爆搜,然后就没过qwq,然后我就想着可以用clock()卡一下时间看看能不能过,但没想的是竟然过了(大概数据太水了吧)下面是我写的代码爆搜的代码(后面有更加高效的方法)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
using namespace std;
int n;
int head[27][20]={0};//head[i][j]i开头的有谁    还有数量
int s[20][3];//记录各单词的首字母和尾字母
char f[120];//输入
int h[25]={0};//记录谁被用了
int coun[27]={0};//记录各首字母的已被使用数量
int score[20];
int maxsum=0,maxn=0;
void dfc(int i,int sum)
{
    if(clock()>CLOCKS_PER_SEC*0.8)//时间到达限制时间的五分之四,直接输出
    {
        cout<<maxsum<<endl;
        exit(0);
    }
    int k=s[i][1]-'A';//第i个单词的尾字母
    if(sum>maxsum)
            maxsum=sum;
    for(int j=1;j<=head[k][0];j++)//查找以k开头的单词
    {
        int t=head[k][j];//t为一k开头的单词下标
        if(h[t]==0)//如果没有备用
        {
            h[t]=1;//i被使用
            coun[k]++;
            dfc(t,sum+score[t]);
            h[t]=0;
            coun[k]--;
        }
    }
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        scanf("%s",f);
        s[i][0]=f[0];//记录首字母
        s[i][1]=f[strlen(f)-1];//记录尾字母
        score[i]=strlen(f);
        maxn+=score[i];
        head[f[0]-'A'][0]++;//首字母为f[0]加一
        head[f[0]-'A'][head[f[0]-'A'][0]]=i;
    }
    for(int i=0;i<n;i++)
    {
        h[i]=1;
        coun[s[i][0]]++;
        dfc(i,score[i]);
        h[i]=0;
        coun[s[i][0]]--;
    }
    cout<<maxsum;
    return 0;
}

下边的代码是用将状态用二进制来表示的,并将其的出来的数据储存在二维数组s[ I ][state]里,算是记忆化搜索(dfs)了吧,用二维数组s[i][state]而不用s[state]是因为相同的状态下其单词的连接顺序可能不同,因此用了二维数组,其中i 表示当前组成的单词最尾端是第i个单词
代码实现

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    char first;
    char endch;
    int len;
}p[20];
int s[20][1<<16]={0};//储存将各单词作为开头的所能达到最大长度
char  f[102];//用于输入/
int n;
int dfs(int x,int state)
{
    if(s[x][state]!=0)
        return s[x][state]+p[x].len;
    char ch;
    ch=p[x].endch;//尾字母
    for(int i=0;i<n;i++)
    {
       if((!((1<<(n-i-1))&state))&&(ch==p[i].first))
       {
           s[x][state]=max(s[x][state],dfs(i,state+(1<<(n-i-1))));
       }
    }
    return s[x][state]+p[x].len;
}
int main()
{
    int maxlen=0;
    char ch;
    scanf("%d%*c",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%s",f);
        p[i].first=ch=f[0];//记录首字母
        int k=strlen(f)-1;//尾字母的下标
        p[i].endch=f[k];//尾字母
        p[i].len=strlen(f);//单词的长度
    }
    for(int i=0;i<n;i++)
    {
           s[i][0]=dfs(i,1<<(n-i-1));
        maxlen=max(maxlen,s[i][0]);
    }
    cout<<maxlen;
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的猜单词游戏代码Python示例: ```python import random # 定义单词列表 WORDS = ['apple', 'orange', 'banana', 'pear', 'grape', 'peach'] # 随机选取一个单词 word = random.choice(WORDS) # 初始化未猜中的字母列表 remaining_letters = list(word) # 初始化猜测结果列表,同样长度的下划线 guesses = ['_' for _ in word] # 定义猜测函数 def guess_letter(): # 输出未猜中的字母列表 print('Remaining letters:', ' '.join(remaining_letters)) # 输出当猜测结果列表 print('Current guess:', ' '.join(guesses)) # 告知玩家剩余可猜测次数 print('You have', chances, 'chances left.') # 获取玩家输入 letter = input('Guess a letter: ').lower() # 检查是否为单个字母 if not letter.isalpha() or len(letter) != 1: print('Please enter a single letter.') return False # 检查是否已经猜过该字母 if letter in remaining_letters: remaining_letters.remove(letter) else: print('You already guessed that letter.') return False # 检查是否为正确的猜测 found = False for i, c in enumerate(word): if c == letter: guesses[i] = letter found = True if not found: print('Incorrect guess.') return False # 检查是否已经猜中所有字母 if '_' not in guesses: print(word) print('Congratulations, you win!') return True else: return False # 主循环 chances = 6 while chances > 0: if guess_letter(): break chances -= 1 # 游戏结束提示 if chances == 0: print('You lose! The word was', word) ``` 运行该代码后,将会得到如下游戏界面: ``` Remaining letters: o r a n g e Current guess: _ _ _ _ _ _ You have 6 chances left. Guess a letter: e Remaining letters: o r a n g Current guess: _ _ _ _ e _ You have 6 chances left. Guess a letter: x Remaining letters: o r a n g Current guess: _ _ _ _ e _ You have 5 chances left. Guess a letter: r Remaining letters: o a n g Current guess: _ _ r _ e _ You have 5 chances left. Guess a letter: g Remaining letters: o a n Current guess: _ _ r _ e _ You have 5 chances left. Guess a letter: p Remaining letters: o a n Current guess: _ _ r _ e _ You have 4 chances left. Guess a letter: o Remaining letters: a n Current guess: _ _ r o e _ You have 4 chances left. Guess a letter: n Remaining letters: a Current guess: _ _ r o n e You have 4 chances left. Guess a letter: a You already guessed that letter. Remaining letters: a Current guess: _ _ r o n e You have 4 chances left. Guess a letter: q Incorrect guess. Remaining letters: a Current guess: _ _ r o n e You have 3 chances left. Guess a letter: t Incorrect guess. Remaining letters: a Current guess: _ _ r o n e You have 2 chances left. Guess a letter: y Incorrect guess. Remaining letters: a Current guess: _ _ r o n e You have 1 chances left. Guess a letter: s Incorrect guess. You lose! The word was orange ``` 在游戏中,玩家每次输入一个字母作为猜测,程序会告诉玩家剩余可猜测次数,并且经过判断,输出当猜测结果,一直到猜中单词或者猜测次数用完结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值