CodeForce-792C Divide by Three(數學)
阿新 • • 發佈:2017-07-03
不一定 pre pan 刪除 判斷 contain 並且 cst esc
Divide by Three
CodeForces - 792C
有一個正整數 n 寫在黑板上。它有不超過 105 位。 你需要通過刪除一些位使得他變成一個美麗的數,並且需要刪除盡量少的位數。刪除的位不一定要連續。
稱一個數為美麗的當且僅當這個數不包含前導0並且是 3 的倍數。舉個例子,0, 99, 10110 是美麗的數,但 00, 03, 122 不是。
如果沒有方案,輸出 -1。 如果有多種方案輸出任意一種。
Input1033Output
33Input
10Output
0Input
11Output
-1
題解:
要讓一個數是美麗的,有兩種方案:
M=(a[1]+a[2]+a[3]+....+a[n])%3
(1)刪除一個數,這個數滿足 a[i]%3=M
(2)刪除兩個數,這兩個數滿足 a[i]%3==3-M
同時註意要判斷存在前導零的情況和刪除數字後串為空的情況。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<cmath> using namespace std; int L, M, i, j, W, A[100000]; bool C; string S, R; int main () { cin>>S; L=S.length(); for (i=0;i<L;i++) { A[i]=S[i]-‘0‘; M=(M+A[i])%3; } if (M==0) {//不用進行刪除 cout<<S<<‘\n‘; return 0; } for (i=1;i<L;i++) {//從第二個數字開始 選擇刪除一個數字 if (A[i]%3==M) { for (j=0;j<i;j++) { cout<<A[j]; } for (j=i+1;j<L;j++) { cout<<A[j]; } cout<<‘\n‘; return 0; } } if (A[0]%3==M&&A[1]!=0) {//還是刪除一個數字(模3為M),這種情況是第二個數字不為0並且可以刪除第一個 for (j=1;j<L;j++) { cout<<A[j]; } cout<<‘\n‘; return 0; } for (i=L-1;i>=0;i--) {//刪除兩個數字(均是模3為3-M) 或更多 if (A[i]%3==3-M) { if (W) {//判斷有兩個可刪數字 for (j=0;j<L;j++) { if (j!=W&&j!=i) {//刪除兩個及以上,可能有前導零 if (A[j]) { C=1; cout<<A[j]; } else if (C) { cout<<0; } } } if (!C) { if (L<3) { cout<<-1<<‘\n‘; } else { cout<<0<<‘\n‘; } } return 0; } else { W=i; } } } if (A[0]%3==M) {//刪除一個數字或更多 這種情況是第一個數字是模3為M,第二個數字為0。這裏先刪除第一個數字 for (j=1;j<L;j++) { if (A[j]) {//可能有前導零 C=1; cout<<A[j]; } else if (C) { cout<<0; } } if (!C) { if (L==1) { cout<<-1<<‘\n‘; } else { cout<<0<<‘\n‘; } } } return 0; } /* //這代碼的選擇刪除 模M 或 模3-M 的順序很重要, 最後兩種方法如果換個先後順序就錯了,比如這組數據 //20000111 //200001 //之前我的做法是同時進行兩種刪除方法,通過判斷哪種方法刪除數字更少,來選擇輸出更優的那個,而這個代碼則不用比較兩種情況,直接按這種順序輸出就行 */
CodeForce-792C Divide by Three(數學)