zoukankan      html  css  js  c++  java
  • cf467D(map,vector,bfs,特点提取)

    D. Fedor and Essay
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    After you had helped Fedor to find friends in the «Call of Soldiers 3» game, he stopped studying completely. Today, the English teacher told him to prepare an essay. Fedor didn't want to prepare the essay, so he asked Alex for help. Alex came to help and wrote the essay for Fedor. But Fedor didn't like the essay at all. Now Fedor is going to change the essay using the synonym dictionary of the English language.

    Fedor does not want to change the meaning of the essay. So the only change he would do: change a word from essay to one of its synonyms, basing on a replacement rule from the dictionary. Fedor may perform this operation any number of times.

    As a result, Fedor wants to get an essay which contains as little letters «R» (the case doesn't matter) as possible. If there are multiple essays with minimum number of «R»s he wants to get the one with minimum length (length of essay is the sum of the lengths of all the words in it). Help Fedor get the required essay.

    Please note that in this problem the case of letters doesn't matter. For example, if the synonym dictionary says that word cat can be replaced with word DOG, then it is allowed to replace the word Cat with the word doG.

    Input

    The first line contains a single integer m (1 ≤ m ≤ 105) — the number of words in the initial essay. The second line contains words of the essay. The words are separated by a single space. It is guaranteed that the total length of the words won't exceed 105 characters.

    The next line contains a single integer n (0 ≤ n ≤ 105) — the number of pairs of words in synonym dictionary. The i-th of the next n lines contains two space-separated non-empty words xi and yi. They mean that word xi can be replaced with word yi (but not vise versa). It is guaranteed that the total length of all pairs of synonyms doesn't exceed 5·105 characters.

    All the words at input can only consist of uppercase and lowercase letters of the English alphabet.

    Output

    Print two integers — the minimum number of letters «R» in an optimal essay and the minimum length of an optimal essay.

    Examples
    input
    Copy
    3
    AbRb r Zz
    4
    xR abRb
    aA xr
    zz Z
    xr y
    output
    2 6
    input
    Copy
    2
    RuruRu fedya
    1
    ruruRU fedor
    output
    1 10
    题意:给你一段有n个单词的句子,再给出m个可以以左代替右的转换(单向的),求整个句子最少有几个r和最少的字母。
    分析:从题意可知我们可以用bfs遍历找出每个单词最优的情况,怎样找出最优的情况呢,我们由题意可知r和整句单词数要最少
    我们就可以从每个单词中提取出r的数量cnt和每个单词的长度len。然后利用map函数中的count找出是否有一样的单词,用v[i][j]数组
    记录第i个单词的可以代替第v[i][j]个单词,v[i].size()可以快捷的找出有多少个单词可由第i个单词代替,具体看代码解析。
    代码:

    #include<cstdio>
    #include<map>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<queue>
    #define Max 100010
    using namespace std;
    typedef __int64 ll;
    map<string,int> mp;//记录不同单词的数量
    vector<int> v[Max*2];//记录第j可以换成i
    int n,m,w[Max];//记录要处理的单词
    int sz;
    struct
    {
      int len;
      int cnt;
    }st[Max*3],st1;//记录每个单词的长度和r的数量
    int dt(string& s)
    {
      int len=s.length();
      int i;
      int cnt=0;
      for(i=0;i<len;i++)//全转换为小写字母以便处理
      {
        if(s[i]<'a')
        s[i]+='a'-'A';
        if(s[i]=='r')
        cnt++;//记录r数
      }
      if(!mp.count(s))//加入不同的单词,mp.count(s)可以查找mp中是否有和s一样的单词
      {
        //printf("sada ");
        mp[s]=sz;//给每个单词标个号
        st[sz].cnt=cnt;
        //printf("%d %d %d ",sz,cnt,len);
        st[sz++].len=len;
      }
    return 0;
    }
    int bfs()
    {
      queue<int> q;
      int i,j;
      for(i=0;i<sz;i++)//放入所有的单词,以便将其全部化为最优情况
      q.push(i);
      //printf("sz=%d ",sz);
      while(!q.empty())
      {
        int a=q.front();
        q.pop();
        st1=st[a];//提取出当前编号单词的特性
        int len=v[a].size();//有多少单词可以由当前单词代替
        for(i=0;i<len;i++)
        {
          int x1=v[a][i];
          //printf("v%d",x1);
          if(st1.cnt<st[x1].cnt)//判断r的数量
          {
            st[x1].cnt=st1.cnt;
            st[x1].len=st1.len;
            q.push(x1);
          }
          else if(st1.cnt==st[x1].cnt&&st1.len<st[x1].len)//判断长度
          {
            st[x1].len=st1.len;
            q.push(x1);
          }
        }
        //printf("a%d %d ",a,q.empty());
      }
      return 0;
    }
    string s1,s2;
    int main()
    {
      cin>>n;
      int i,j;
      for(i=0;i<n;i++)
      {
        getchar();
        cin>>s1;
        dt(s1);
        w[i]=mp[s1];//记录要处理的单词
      }
      cin>>m;
      for(i=0;i<m;i++)
      {
        cin>>s1>>s2;
        dt(s1);
        dt(s2);
        v[mp[s2]].push_back(mp[s1]);//注意:单词的转换是由左到右,单向的;
      }
      bfs();
      ll cnt=0,len=0;//小心cnt与len超过2^32(每个单词<=100000,每条语句小于100000个单词
      for(i=0;i<n;i++)//因为前面的处理已将所有单词转换为最优情况了
      {
        cnt+=st[w[i]].cnt;
        len+=st[w[i]].len;
      }
      cout<<cnt<<" "<<len;
      return 0;
    }

  • 相关阅读:
    【蜕变之路】第20天 UUID和时间戳的生成 (2019年3月10日)
    3.EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因(系列4)
    reactnative资源
    代码
    模板匹配模型、原型模型和区别性特征模型各自如何解释汉字的知觉
    mysqldatadir 转移
    mysql主从设置windows
    心灵鸡汤
    测试的发现遗漏BUG的做法
    汉字模式匹配的过程
  • 原文地址:https://www.cnblogs.com/cglongge/p/8678621.html
Copyright © 2011-2022 走看看