1. 程式人生 > >CodeForce-792C Divide by Three(數學)

CodeForce-792C Divide by Three(數學)

不一定 pre pan 刪除 判斷 contain 並且 cst esc

Divide by Three

CodeForces - 792C

有一個正整數 n 寫在黑板上。它有不超過 105 位。 你需要通過刪除一些位使得他變成一個美麗的數,並且需要刪除盡量少的位數。刪除的位不一定要連續。

稱一個數為美麗的當且僅當這個數不包含前導0並且是 3 的倍數。舉個例子,0, 99, 10110 是美麗的數,但 00, 03, 122 不是。

如果沒有方案,輸出 -1。 如果有多種方案輸出任意一種。

Input
1033
Output
33
Input
10
Output
0
Input
11
Output
-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(數學)