Codeforces 792C. Divide by Three 贪心+分类讨论
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 792C. Divide by Three 贪心+分类讨论相关的知识,希望对你有一定的参考价值。
题意:给一个数字字符串,让你删除尽可能少的数位,使得这个数能够被3整除,并且不能有前导0存在。
思路:所有数位加起来%3得到的值mod,那么就有三种情况
mod==0:直接输出
mod==1:要么删除一个数位%3=1的数,要么删除两个数位%3=2的数
mod==2:要么删除一个数位%3=2的数,要么删除两个数位%3=1的数
其中前导零有个大坑,如果我们删数位的两种情况都可以,但是有一种情况会导致删除前导零,删除前导零的位数也要计算进去,细节很重要。为了尽可能的少产生前导零,当我们删除数位的时候,应该从后往前删除。(这个过程我用了栈来存储,分别算了两种情况的删除位数 然后作比较)
丑陋的AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e9+7; char num[100100]; int deal_1[100100]; bool vis_1[100100]; int deal_2[100100]; bool vis_2[100100]; stack<int> sta1,sta2; //sta1存放%3值为1的数位置的下标 sta2同理 int len; int del_cnt1,del_cnt2; bool flag; void print(int n) { if(n==1) { if(del_cnt1==len) { if(flag) { printf("0\n"); } else printf("-1\n"); return; } for(int i=0; i<len; i++) if(vis_1[i]) printf(("%c"),num[i]); } else { if(del_cnt2==len) { if(flag) { printf("0\n"); } else printf("-1\n"); return; } for(int i=0; i<len; i++) if(vis_2[i]) printf(("%c"),num[i]); } printf("\n"); } void del(int n) //计算前导0 { int cnt=0; if(n==1) { for(int i=0; i<len; i++) if(vis_1[i]) { if(num[i]!=‘0‘) return; else if(del_cnt1) { vis_1[i]=false; ++del_cnt1; } } } else if(n==2) { for(int i=0; i<len; i++) if(vis_2[i]) { if(num[i]!=‘0‘) return; else if(del_cnt2) { vis_2[i]=false; ++del_cnt2; } } } } int main() { memset(vis_1,true,sizeof(vis_1)); memset(vis_2,true,sizeof(vis_2)); del_cnt1 = del_cnt2 = maxn; flag = false; len = strlen(num); int mod =0; for(int i=0; i<len; i++) { if(!flag && num[i]==‘0‘) flag=true; deal_2[i] = deal_1[i] = (num[i]-‘0‘)%3; mod += deal_1[i]; if(deal_1[i]==1) sta1.push(i); else if(deal_2[i]==2) sta2.push(i); } mod%=3; if(mod == 0) { printf("%s\n",num); return 0; } else if(mod == 1) { if(!sta1.empty()) { del_cnt1=0; vis_1[sta1.top()] = false; ++del_cnt1; del(1); } if(sta2.size()>=2) { del_cnt2=0; vis_2[sta2.top()] = false; sta2.pop(); vis_2[sta2.top()] = false; sta2.pop(); del_cnt2+=2; del(2); } } else { if(!sta2.empty()) { del_cnt1=0; vis_1[sta2.top()] = false; ++del_cnt1; del(1); } if(sta1.size()>=2) { del_cnt2=0; vis_2[sta1.top()] = false; sta1.pop(); vis_2[sta1.top()] = false; sta1.pop(); del_cnt2+=2; del(2); } } if(del_cnt1>del_cnt2) print(2); else print(1); return 0; }
以上是关于Codeforces 792C. Divide by Three 贪心+分类讨论的主要内容,如果未能解决你的问题,请参考以下文章
Divide by Three CodeForces - 792C
CodeForces 792C - Divide by Three [ 分类讨论 ]
CodeForce-792C Divide by Three(数学)