例题:填词-poj

    1. 问题描述

      Alex喜欢填词游戏。填词游戏是一个非常简单的游戏。填词游戏包括一个N X M大小的矩形方格盘和P个单词。玩家需要把每个方格中填上一个字母使得每个单词都能在方格盘上被找到。每个单词都能被找到要满足下面的条件:

      每个方格都不能同时属于超过一个的单词。一个长为k的单词一定要占据k个方格。单词在方格盘中出现的方向只能是竖直的或者水平的(可以由竖直转向水平,反之亦然)。

      你得任务是首先在方格盘上找到所有的单词,当然在棋盘上有些方格可能没有被单词占据,然后把这些没有用的方格找出来,再把这些方格上的字母按照字典序组成一个“神秘单词”。

    2. 输入数据 
      输入的第一行包括3个整数N,M和P(2<= M,N<=10,0<=P<=100)。接下来的N行,每行包括M个字符,来表示方格盘。接下来的P行给出需要在方格盘中找到的单词。
    3. 输出要求 
      输入保证填词游戏至少有一组答案。输入中给出的字母都是大写字母。
    4. 输入样例 
      3 2 2 
      E B G 
      G E E 
      E G E 
      B E G 
      G E E
    5. 输出样例 
      E E G
    6. 解题思路 
      题目中给出的条件比较隐晦。输入中给出的字母都是大写字母——表明输出也是只有大写字母。输入保证填词游戏至少有一组答案——这说明不必寻找单词所在的位置只要去掉这些单词所占用的字母就可以了。“神秘单词”中的字母要按照单词字典序给出——说明只要知道“神秘单词”中的字母组成就可以了,在字母组成确定的情况下,按字典序输出的方式只有一种。分析到这里我们发现这其实是个很简单的问题:给出一个字母的集合,从中去掉一些在给出单词中出现过的字母,将剩下的字母按字典序输出即可。 
      可以定义一个有26个元素的数组,分别记录在输入的矩形中每个字母出现的次数,当读完单词时,将数组中对应到单词中的字母的元素减一。处理完所有的单词后,将数组中德非0的元素对应的字母一次输出,数组元素的值是几,就输出几次该字母。
    7. 代码:
    8. #include<iostream>
      #include<stdio.h>
      using namespace std;
      int max(int x,int y)
      {
      
          return x>y?x:y;
      }
      int main()
      {
          int N,M,P;
          int i,j;
          int Letter[26];
          for(i=0;i<26;i++)
          {
              Letter[i]=0;
          }
          for(i=0;i<26;i++)
          {
              cout<<Letter[i];
          }
          cin>>N>>M>>P;
          for(i=0;i<N;i++)
          {
              char str[100];
              cin>>str;
              for(j=0;str[j]!=‘\0‘;j++)
              {
      
                  Letter[str[j]-‘A‘]++;
                  printf("%c  %d\n",str[j],Letter[str[j]-‘A‘]);
              }
          }
      
          cout<<endl<<endl;
          for(j=0;j<P;j++)
          {
              char str1[100];
              cin>>str1;
              for(int k=0;str1[k]!=‘\0‘;k++)
              {
                  Letter[str1[k]-‘A‘]--;
                  printf("%c  %d\n",str1[k],Letter[str1[k]-‘A‘]);
              }
          }
          cout<<endl;
          for(i=0;i<26;i++)
          {
              if(Letter[i]!=‘\0‘)
              for(j=0;j<Letter[i];j++)
              {
                  printf("%c",i+‘A‘);
              }
          }
          cout<<endl;
          return 0;
      }
      /*
      3 3 2
      EBG
      GEE
      EGE
      BEG
      GEE
      */

      实际上M拿来没什么nuan用!没有去控制单词长度,可以去掉!

时间: 2024-10-12 12:50:57

例题:填词-poj的相关文章

带权并查集(含种类并查集)【经典模板】 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug&#39;s life(简单) ③hihoCoder 1515 : 分数调查

带权并查集: 增加一个 value 值,并且每次合并和查找的时候需要去维护这个 value 例题一 :POJ 1182 食物链(经典) 题目链接:https://vjudge.net/contest/339425#problem/E 带权并查集的解法 定义两个数组fa[ ]和rela[ ],fa用来判断集合关系,rela用来描述其与根节点的关系.因为关系满足传递性,所以可以推导出给出条件下的当前关系,在判断与之前已有关系是否矛盾. 本题的解法巧妙地利用了模运算,rela数组用0表示同类,1表示当

0-1背包问题,附上例题(POJ - 3624 Charm Bracelet)

0-1背包问题的题目样式 有 N 件物品和一个容量为 M 的背包.放入第 i 件物品耗费的费用是 Wi,得到的价值是 Vi.求解将哪些物品装入背包可使价值总和最大. 0-1背包问题关键在于该物品放或不放,即在当前容量为M的的情况下,选择不选择该物品,那么就有一个转移方程 for(i=0  -  N) for(j=0  -  M) dp[i][j] = max(dp[i-1][j],dp[i-1][j+w[i]]+v[i]); 当前物品为i,当前的背包容量为j,如果不选当前该物品,则选取dp[i-

图的全局最小割的Stoer-Wagner算法及例题

Stoer-Wagner算法基本思想:如果能求出图中某两个顶点之间的最小割,更新答案后合并这两个顶点继续求最小割,到最后就得到答案. 算法步骤: ------------------------------------------------------------------------------------------------------------------------- (1)首先初始化,设最小割ans = INF                                

点分治 理解及例题

点分治,基于点的分治: 其思路为: 子树结构:子树结构虽然的确是某点的一个子树,但我们讨论点分治时,相当于把这个子树摘下来,当做无根树处理: 对于一个子树结构: 处理子树结构的某个单点(未必是原根): 以这个被处理的点为新根,找出她的子树,变成递归下一层要处理的子树结构: 递归下一层: 在一个常见的,约定俗成的写法下(就是一个“说点分治就是指她”的写法) 其时间复杂度可以达到O(logn*f(num(1)) (num(i)为处理第i个单点时的数据范围): (f(i)为处理数据范围为i的单点的时间

判断两条直线的位置关系 POJ 1269 Intersecting Lines

两条直线可能有三种关系:1.共线     2.平行(不包括共线)    3.相交. 那给定两条直线怎么判断他们的位置关系呢.还是用到向量的叉积 例题:POJ 1269 题意:这道题是给定四个点p1, p2, p3, p4,直线L1,L2分别穿过前两个和后两个点.来判断直线L1和L2的关系 这三种关系一个一个来看: 1. 共线. 如果两条直线共线的话,那么另外一条直线上的点一定在这一条直线上.所以p3在p1p2上,所以用get_direction(p1, p2, p3)来判断p3相对于p1p2的关

《挑战程序设计竞赛》2.4 加工并存储数据的数据结构

这个章节一共介绍了几种数据结构:堆,二叉搜索树,并查集. 第一部分 堆. 堆的实现: int heap[maxn]; void push(int x) { int i = sz;//自己结点的编号 while(i > 0) { int p = (i - 1) / 2; if(heap[p] <= x) break; heap[i] = heap[p]; i = p; } heap[i] = x; } int pop() { int ret = heap[0];//取出优先级最高的元素 int

二分图最大匹配总结

hdoj1528 二分匹配模版: 代码: 1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 using namespace std; 7 #define N 220 8 9 int n, maps[N][N], vis[N], used[N]; 10 11 struct node 12 {

背包问题总结

刷到背包了,背包是一类问题,开个总结记录贴 1 01 背包问题 题意:有N 件物品和一个容量为V 的背包.放入第i 件物品耗费的费用是Ci,得到的价值是Wi.求解将哪些物品装入背包可使价值总和最大 思路:用子问题定义状态:即f[i,v] 表示前i 件物品恰放入一个容量为v 的背包可以获得的最大价值.则其状态转移方程便是: f[i,v]=max(f[i,v],f[i-1,v-ci]+wi) 伪代码 通过递减顺序V~0,我们可以在每个i循环完后得到最终的状态,即可以省略i 对于恰好装满背包,需要初始

树状数组总结

树状数组 数据结构知识点1-树状数组 树状数组的用途就是维护一个数组,重点不是这个数组,而是要维护的东西,最常用的求区间和问题,单点更新.但是某些大牛YY出很多神奇的东西,完成部分线段树能完成的功能,比如区间更新,区间求最值问题. 树状数组当然是跟树有关了,但是这个树是怎么构建的呐?这里就不得不感叹大牛们的脑洞之大了,竟然能想出来用二进制末尾零的个数多少来构建树以下图为例: 从上图能看出来每一个数的父节点就是右边比自己末尾零个数多的最近的一个,也就是x的父节点就是x+(x&(-x)),这里为什么