zoukankan      html  css  js  c++  java
  • luogu【P2753】[USACO4.3]字母游戏Letter Game

    这个题。。。一开始看了很久题目(并且问了机房几个大佬)才明白题意。。 (原题入口

    题意
    大概是一开始给你一些字母出现的次数 你之后组成的单词(最多两个单词)每个字母出现次数 必须小于或等于标准(standard)的次数
    其次是要满足你组成单词的 每个字符个数 * 该字符单个价值 最大。 如果有多解按字典序来。

    自己的理解:
    这个题目很良心 单词表可以去USACO官网上看。。都很短 而且给你的是按字典序来的 就不需要手动排序了
    再其次楼下都讲了 很多单词存都不用存 一开始判断下就行了
    对于这种东西 就应该用结构体存储 并且重载一些运算符 或者 成员函数 (因为很多操作是很重复的)
    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <cctype>
     7 #include <iostream>
     8 #define For(i, l, r) for(int i = (l); i <= (int)(r); ++i)
     9 #define Fordown(i, r, l) for(int i = (r); i >= (int)(l); --i)
    10 #define Set(a, v) memset(a, v, sizeof(a))
    11 using namespace std;
    12 
    13 inline int read(){
    14   int x = 0, fh = 1; char ch;
    15   for(; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
    16   for(; isdigit(ch); ch = getchar()) x = (x<<1) + (x<<3) + (ch^'0');
    17   return x * fh;
    18 }
    19 
    20 const int N = 40010;
    21 const int score[26]={2, 5, 4, 4, 1, 6, 5, 5, 1, 7, 6, 3, 5, 2, 3, 5, 7, 2, 1, 2, 4, 6, 6, 7, 5, 7}; 
    22 //当然要把这个表打出来了。。但我太懒了。。copy了一下redbag大神的。。 
    23 
    24 struct node {
    25     char str[101];
    26     int dig[26]; //存储了每个单词出现的次数 
    27 
    28     void update () {
    29         int n = strlen(str);
    30         Set(dig, 0);
    31         For (i, 0, n-1) 
    32             dig[str[i] - 'a'] ++;
    33     } //更新每个字符出现的次数 
    34     
    35     int calc () {
    36         int ans = 0;
    37         For (i, 0, 25)
    38             ans += dig[i] * score[i];
    39         return ans;
    40     } //计算这个单词的得分 
    41 
    42     bool operator > (const node &rhs) const {
    43         For (i, 0, 25)
    44             if (dig[i] > rhs.dig[i]) return true;
    45         return false;
    46     } //比较单词每个字母出现次数多少 如果多的话 则不满足题目要求 
    47     
    48     node operator + (const node &rhs) const {
    49         node ans;
    50         Set(ans.dig, 0);
    51         For (i, 0, 25)
    52             ans.dig[i] = dig[i] + rhs.dig[i];
    53         return ans;
    54     } //把两个单词出现次数加起来 
    55 };
    56 
    57 node standard, word[N];
    58 int cnt = 1;
    59 struct ans_pair {
    60     int word1, word2; //答案的词对 如果只有一个单词则第二个为0 这个存储的是单词的编号 
    61 };
    62 
    63 #include <vector>
    64 vector <ans_pair> lt; //听说 不定长数组 和 答案序列 更配哦 (滑稽) 
    65 
    66 int ans_num = 0;
    67 int main(){
    68     scanf ("%s", standard.str);
    69     standard.update(); //把初始的标准更新 
    70     while (scanf ("%s", word[cnt].str) != EOF && word[cnt].str[0] != '.') {
    71         word[cnt].update();
    72         if (word[cnt] > standard) continue; //如果不满足要求就不能存储 让下一个输入的覆盖掉 
    73         ++cnt;
    74     }
    75     --cnt; //去掉最后一个'.' 
    76     For (i, 1, cnt)  {
    77         int now_score = 0; //当前成绩 
    78         now_score = word[i].calc();  
    79         if (now_score > ans_num) 
    80         {ans_num = now_score; lt.clear(); lt.push_back((ans_pair) {i, 0} );} //比原来答案大 就更新一下 
    81         else if (now_score == ans_num) lt.push_back((ans_pair) {i, 0} ); //相同就放入vector 
    82 
    83         For (j, i+1, cnt) {
    84             node new_word = word[i] + word[j]; //计算合并后单词的dig 
    85             if (new_word > standard ) continue; //不满足要求就继续找 
    86             now_score = new_word.calc(); //计算成绩 
    87             if (now_score > ans_num)  //同上 
    88             {ans_num = now_score; lt.clear(); lt.push_back((ans_pair) {i, j} );}
    89             else if (now_score == ans_num) lt.push_back((ans_pair) {i, j} );
    90         }
    91     }
    92 
    93     printf ("%d
    ", ans_num);
    94     For (i, 0, lt.size()-1) {
    95         int fir = lt[i].word1, sec = lt[i].word2; //first 第一个单词 second 第二个单词 
    96         if (sec) printf ("%s %s
    ", word[fir].str, word[sec].str);  
    97          else printf ("%s
    ", word[fir].str); //如果只有一个单词 输出第一个单词就好了 
    98     }
    99 }
  • 相关阅读:
    Linux命令-chmod、chown和chgrp
    UUID是如何保证全局唯一的
    Java实现HTML转换为PDF的常见方法
    Java内存溢出详解
    Java 版本6下载大全
    spring 标签
    java 静态成员访问
    Java开发之@PostConstruct执行顺序
    Java集合和数组的区别
    集合转数组的toArray()和toArray(T[] a)方法
  • 原文地址:https://www.cnblogs.com/zjp-shadow/p/7140713.html
Copyright © 2011-2022 走看看