1. 程式人生 > >hihoCoder #1871 : Heshen's Account Book-字串暴力模擬 自閉(getline()函式) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction B) 2018 ICPC 北京區域賽現場賽B

hihoCoder #1871 : Heshen's Account Book-字串暴力模擬 自閉(getline()函式) (ACM-ICPC Asia Beijing Regional Contest 2018 Reproduction B) 2018 ICPC 北京區域賽現場賽B

P2 : Heshen's Account Book

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') 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('\n');
 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=='\n'){
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 */

 

 

 

 

 

 

極度自閉的暴力模擬題,誰頭髮多或者閒得無聊,這是一個好題。