• hihoCoder #1871 : Heshen's Account Book-字符串暴力模拟 自闭(getline()函数) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction B) 2018 ICPC 北京区域赛现场赛B


    Time Limit:1000ms
    Case Time Limit:1000ms
    Memory Limit:512MB

    Description

    Heshen was an official of the Qing dynasty. He made a fortune which could be comparable to a whole country's wealth by corruption. So he was known as the most corrupt official in Chinese history. But Emperor Qianlong liked, or even loved him so much that was not punished during Qianlong's regime even everybody knew he was totally corrupted.

    After Qianlong quit his job, his son Jiaqing took the throne. The new Emperor hated Heshen very much, so he threw Heshen into jail and awarded him death immediately after Qianlong died. Of course Jiaqing would not forget to raid Heshen's house for money --- that was the story of "Heshen fell, Jiaqing full."

    Jiaqing's man got a notebook from Heshen's home which was obviously an account book.But the text of the book was written in English! Jiaqing thought all numbers in that account book should stand for money. Please find out all numbers for Jiaqing.

    The text of the account book consists only lower case letters, spaces, and digits
    ('0' - '9'). One or several consecutive digits form a number. But Jiaqing only cared about the ACTUAL numbers among all numbers. Only if a number DOESN'T satisfy any of the conditions below, it is an ACTUAL number:

    1) The character to the left of the number is a lower case letter, for example: a123

    2) The character to the right of the number is a lower case letter, for example: 123b

    3) The number has one or more extra leading zeros, such as 01 , 0012….

    Please note that if the last character of a line is a digit, and the first character of the next line is also a digit, those two digits are considered consecutive.

    Input

    There are no more than 200 lines. The length of each line is no more than 1000 characters.

    And it is guaranteed that every number's length is no more than 18.

    There may be spaces at the end of a line, and those spaces matter.

    No blank lines in the input. A line consisting of only spaces is not a blank line.

    Output

    Print all ACTUAL numbers in a single line in the original order.
    Then, count the number of ACTUAL numbers of each line, and print them. A number X only belongs to the line which contains the first digit of X.

    Sample Explanation

    We assume there is no spaces at the end of each line in the Sample Input.

    In the sample input, the '3' at the end of the second line and the '2' at the beginning of the third line are considered consecutive, so "1323" is a number.  But this number only belongs to the second line, so the third line has only 2 numbers ---- 14 and 344..
    Sample Input
    a19 01 17b
    12 bdc 13
    23 14 344 bc
    Sample Output
    12 1323 14 344
    0
    2
    2

    题意就是给你一段文本,让你从里面找出来所有的ACTUAL  numbers,就是找出来数字,仅由0-9的数组成,没有字母,并且没有前导零。输出来所有满足条件的数字,然后再输出每一行有多少个数字。

    有一个小tip:如果上一行的最后一个是数字,下一行的开头也是数字,要连在一起,计数的时候记到上一行,下一行就不计这个数。

    这个题是真的自闭,写得好的(姿势对的)一次就能过,写不好的,写到没脾气也过不了。交了26遍才过。。。

    可能是我太捞了,也可能就是不能用getchar,用getchar写的过不了,用getline写的可以过。

    数据怎么结束输入,就是输完数据换行之后按Ctrl+Z就可以了。

    题目坑点:

    1.因为题目上说数字的长度最长不超过18,我一开始眼瞎没看到,写的int,后面改成用字符串存的。

    2.上一行最后一个如果为数字,下一行的开头也是数字的话,要连在一起。这里有好几个坑点样例:上一行最后如果满足并且只有一个数字为0,下一行为满足的数字,那么连在一起是不满足的,这是有前导零的情况。如果只有一个零,这是满足的。还有一种是上一行最后是满足情况的数字,但是下一行是不满足的,比如上一行最后为124,下一行开头为3456c,这种事不满足的。然后就是接下来的几行都是数字,比如第一行为erty 56,第二行为2462,第三行为357245,这种是都要连在一起的。还有就是上一行最后是不满足情况的,但是最后一个是数字的,这种是不满足的,举例:上一行最后为c124,下一行开始为45674,这种情况下,45674是不计数的,因为连在一起是不满足情况的。

    3.题目上说的是文本仅由小写字母,数字和空格组成,所以要考虑一下空格,如果上一行为r45 (空格)下一行为123,那么123是不受上面的影响的。

    4.我感觉数据可能有点迷,也可能是我太捞了,因为题目上说文本只由小写字母,数字和空格组成,但是样例输入的话肯定是需要换行才能输入下一行的吧,要不然怎么输入下一行???我读入数据的时候,用getchar读入,通过判断是否为回车来换行,应该没错吧,因为题目上说了没有空行,只有空格的行不是空行,但是我getchar可以读入空格呀,没毛病呀,老铁。但是我这样并没有写过,不管我程序中间判断字母的时候最后是通过换行判断还是通过长度是否等于该行长度判断,都不对,而且我后面试了不存换行,也写不过,但是我换成getline读入,就过了。特意去查了一下getline,系统默认情况下,getline是一行一行读入,用字符串存数据就可以,回车结束输入,或者读完文件结束。但是从某种方面来讲,测试数据也是通过换行写下一行的,所以讲道理,我用getchar读数据应该也不会错才对,但是我getchar就是过不了,最后改成getline才能过。也可能是我用vector存数据存错了???,不知道啊,真是让人没脾气的暴力模拟题。

    可能坑点个人总结的不完整,代码注释里写了,而且一些特殊样例自己也猜出来了,存了一下。贴到下面。

    直接代码:

      1 //B-字符串暴力模拟-A了
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<bitset>
      7 #include<cassert>
      8 #include<cctype>
      9 #include<cmath>
     10 #include<cstdlib>
     11 #include<ctime>
     12 #include<deque>
     13 #include<iomanip>
     14 #include<list>
     15 #include<map>
     16 #include<queue>
     17 #include<set>
     18 #include<stack>
     19 #include<vector>
     20 #include<istream>
     21 using namespace std;
     22 typedef long long ll;
     23 typedef long double ld;
     24 typedef pair<int,int> pii;
     25 
     26 const double PI=acos(-1.0);
     27 const double eps=1e-6;
     28 const ll mod=1e9+7;
     29 const int inf=0x3f3f3f3f;
     30 const int maxn=1000+10;
     31 const int maxm=2e5+10;
     32 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     33 
     34 //vector<char> ve[maxn];
     35 vector<string> ans;
     36 int num[maxn];
     37 string str[maxn];
     38 string ve[maxn];
     39 
     40 int main()
     41 {
     42     char c;
     43     int n=0;
     44     int tmp=0;
     45 //    while((c=getchar())!=EOF){
     46 //        ve[n].push_back(c);
     47 //        if(c=='
    ') n++;
     48 //    }
     49     while(getline(cin,ve[tmp++])){}
     50 //    for(int i=0;i<tmp-1;i++){
     51 //        for(int j=0;j<str[i].size();j++){
     52 //            ve[n].push_back(str[i][j]);
     53 //        }
     54 //        ve[n].push_back('
    ');
     55 //        n++;
     56 //    }
     57     tmp--;
     58 //    cout<<tmp<<endl;
     59     int flag=0,flag1=0,cnt=0,ove=-1,pos=-1;//flag是前导零,数字中有字母的判断,flag1是判断上一行最后一个是不是数字,cnt为当前行数字个数计数,ove是上一行最后是否为满足的数字,pos为最后满足条件的数为第几行
     60     string h;//用字符串暂时存数,害怕超范围
     61     //for(int i=0;i<n;i++){
     62     for(int i=0;i<tmp;i++){
     63         cnt=0;int len=0;
     64         //char pre=*(ve[i].end()-2);//pre为当前行的最后是否为数字,以便来看是否会影响下一行
     65         //for(auto it:ve[i]){//遍历
     66         for(int j=0;j<ve[i].size();j++){
     67             len++;
     68             if(flag1==1) flag=1,flag1=0;//如果上一行的最后一个字母为数字,并且为不满足的条件,举例:c12
     69             //if(it>='0'&&it<='9'&&flag!=1){
     70             if(ve[i][j]>='0'&&ve[i][j]<='9'&&flag!=1){
     71                 if(h.size()==0) //h+=it;
     72                     h+=ve[i][j];
     73                 else if(h[0]=='0'){//如果存在前导零的条件,就标记flag,清空h,把上一行的去掉,因为多加了。
     74                     flag=1,h.clear();
     75                     num[pos]--;pos=-1;//位置标记赋初值
     76                 }
     77                 //else h+=it;
     78                 else h+=ve[i][j];
     79             }
     80             //else if(it==' ')
     81             else if(ve[i][j]==' '){
     82                 if(ove==1&&h.size()==0){num[pos]--;pos=-1;ove=-1;}//上一行的最后是对的,但是和下一行接起来是错的,上一行要减去
     83                 if(h.size()!=0){//如果为满足情况的数字
     84                     ans.push_back(h);
     85                     h.clear();
     86                     cnt++;
     87                     if(ove==1) cnt--,pos=-1,ove=-1;//如果满足,并且是和上一行接起来的,这一行的不计数
     88                 }
     89                 h.clear(),flag=0;//标记清空
     90             }
     91             //else if(it>='a'&&it<='z')
     92             else if(ve[i][j]>='a'&&ve[i][j]<='z'){
     93                 if(ove==1&&h.size()!=0){//如果上一行为满足情况的数字
     94                     if(len==1){//如果下一行的第一个为字母,说明不影响上一行,把上一行的数字存进去
     95                         ans.push_back(h);//上一行最后满足,当前行第一个为字母,为上一行的满足的
     96                         ove=-1;pos=-1;
     97                     }
     98                     else{
     99                         num[pos]--;pos=-1;ove=-1;//如果上一行最后和下一行的接起来是不满足的,那么就要减去上一行的,举例上一行最后为2355,下一行开始为34b
    100                     }
    101                 }
    102                 h.clear(),flag=1;
    103             }
    104             if(j==ve[i].size()-1){
    105                 if(h.size()!=0){
    106                     ove=1;
    107                     if(pos==-1){
    108                         pos=i;cnt++;
    109                     }
    110                 }
    111                 else{
    112                     if(ve[i][ve[i].size()-1]>='0'&&ve[i][ve[i].size()-1]<='9') flag1=1;
    113                     ove=-1;
    114                 }
    115                 flag=0;
    116             }
    117 //            else if(it=='
    '){
    118 //                if(h.size()!=0){//当前行最后为满足的
    119 //                    ove=1;//标记
    120 //                    if(pos==-1){//如果当前位置未标记,说明是满足情况的最一开始的行数,举例,第一行最后为22,下一行为5467,再下一行为3234,标记为22的位置
    121 //                        pos=i;cnt++;//记录位置
    122 //                    }
    123 //                }
    124 //                else{
    125 //                    if(pre>='0'&&pre<='9') flag1=1;//特殊情况,一种是c23这种,下一行开头如果为数字是不成立的,另一种就是前导零,如果上一行最后为0,接下来几行都是数字,那么接下来的几行都是不满足的
    126 //                    ove=-1;
    127 //                }
    128 //                flag=0;//标记清空
    129 //            }
    130         }
    131         num[i]=cnt;
    132         if(i==tmp-1&&h.size()!=0){
    133             ans.push_back(h);//如果为最后一行并且最后的满足,那么就加进去
    134         }
    135     }
    136     vector<string>::iterator it;
    137     for(it=ans.begin();it!=ans.end();it++){//输出所有数字
    138         if(it!=ans.end()-1) cout<<*it<<" ";
    139         else cout<<*it<<endl;
    140     }
    141 //    for(int i=0;i<n;i++)//输出每一行的数字个数
    142 //        cout<<num[i]<<endl;
    143     for(int i=0;i<tmp;i++)
    144         cout<<num[i]<<endl;
    145 }

    这代码写的无语啊。

    下面是我想的样例:

      1 /*
      2 
      3 in1
      4 a19 01 17b
      5 12 bdc 13
      6 23 14 344 bc
      7 
      8 out
      9 12 1323 14 344
     10 0
     11 2
     12 2
     13 
     14 in2
     15 a19 01 17b
     16 12 bdc 13 0
     17 23 14 344 bc
     18 
     19 out
     20 12 13 14 344
     21 0
     22 2
     23 2
     24 
     25 in3
     26 a19 01 17b
     27 12 bdc 13 0
     28 cd 14 344 bc
     29 
     30 out
     31 12 13 0 14 344
     32 0
     33 3
     34 2
     35 
     36 in4
     37 a19 0 17b
     38 12 bdc 13 0
     39 cd 14 344 bc
     40 
     41 out
     42 0 12 13 0 14 344
     43 1
     44 3
     45 2
     46 
     47 in5
     48 a19 01 17b
     49 12 bdc 13
     50 (有一个空格) 23 14 0 bc
     51 
     52 out
     53 12 13 23 14 0
     54 0
     55 2
     56 3
     57 
     58 in6
     59 4
     60 3
     61 2
     62 1
     63 
     64 out
     65 4321
     66 1
     67 0
     68 0
     69 0
     70 
     71 in7
     72 12 13
     73 b
     74 v
     75 c
     76 
     77 out
     78 12 13
     79 2
     80 0
     81 0
     82 0
     83 
     84 in8
     85 12 13
     86 b
     87 d
     88 0
     89 
     90 out
     91 12 13 0
     92 2
     93 0
     94 0
     95 1
     96 
     97 in9
     98 12 c13
     99 21 34
    100 
    101 out
    102 12 34
    103 1
    104 1
    105 
    106 in10
    107 0
    108 0
    109 0
    110 
    111 out
    112 0
    113 0
    114 0
    115 
    116 in11
    117 0
    118 
    119 out
    120 0
    121 1
    122 
    123 in12
    124 12 a15 9
    125 12356
    126 54wf 6
    127 
    128 out
    129 12 6
    130 1
    131 0
    132 1
    133 
    134 in13
    135 12 0
    136 23
    137 45
    138 67 78
    139 
    140 out
    141 12 78
    142 1
    143 0
    144 0
    145 1
    146 
    147 in14
    148 a19 01 9
    149 123 (有一个空格)
    150 56t 67
    151 
    152 out
    153 9123 67
    154 1
    155 0
    156 1
    157 
    158 */

    极度自闭的暴力模拟题,谁头发多或者闲得无聊,这是一个好题。

  • 相关阅读:
    获取本机IP,用户代理
    10 种机器学习算法的要点(附 Python)(转载)
    怎么查找执行比较慢的sql语句-DBA给的建议
    .net 调度器怎么实现心跳(socket除了他,没选择吧)
    分布式多计算机调度平台
    续【C# 以管理员方式启动Winform,进而使用管理员控制Windows Service】
    C# 以管理员方式启动Winform,进而使用管理员控制Windows Service
    SqlServer2008根据现有表,获取该表的分区创建脚本
    SqlServer常用命令
    创建分区表过程
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9979070.html
Copyright © 2020-2023  润新知