codeforces 792CDivide by Three(两种方法:模拟、动态规划
传送门:https://codeforces.com/problemset/problem/792/C
题意:给你一个字符串,要求让你删除最少个数的元素,使得最终答案是没有前导0并且是3的倍数。
题解:模拟:既然是3的倍数,那么第一步肯定是将每个都模上3,讨论长度为1的特殊情况,然后,我们讨论数字模上 3后的和sum
如果sum为0 直接输出,
如果sum为1,我们就要删去一个mod3为1的数或者两个mod3为2的数
如果sum为2,我们就要删去一个mod3为2的数或者两个mod3为1的数
代码如下:
#include<bits/stdc++.h>
using namespace std;
char s[];
int a[];
int t,flag,n,p;
int main(){
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;i++){
t=(t+s[i])%;
a[s[i]%]++;
}
//相加和为0直接输出
if(!t){
puts(s+);
return ;
}
for(p=;s[p]=='';p++);
p-=; if(a[t]&&n>&&(p<=||a[t]>||s[]%!=t))
a[t]--;
else if(a[-t]>&&n>)
a[-t]-=;
else if(a[t]&&n>)
a[t]--;
else {
puts("-1");
return ;
}
/*
t==1,那么我们可以删去一个模3等于1的数字位,
或者删去两个模3等于2的数字位(这个很容易漏)。
*/
/*
t==2,可以删去一个模3等于2的数字位,
或者删去两个模3等于1的数字位。
*/
for(int i=;i<=n;i++){
if(s[i]==''&&!flag) continue;
if(a[s[i]%]) {
putchar(s[i]);
a[s[i]%]--;
flag=;
}
}
if(!flag) puts("");
}
动态规划:
设定dp[i][3]=x表示:
1.dp[i][0]:[0~i]中剩余的数字每个位子相加模3为0的删除最少元素的个数。
2.dp[i][1]:[0~i]中剩余的数字每个位子相加模3为1的删除最少元素的个数。
3.dp[i][2]:[0~i]中剩余的数字每个位子相加模3为2的删除最少元素的个数。
dp[i][j]=min(dp[i][j],dp[i-1][((j-a[i]%3)%3+3)%3)];
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int mod = ;
const int maxn = 1e5+;
const int INF = 0x3f3f3f3f;
int dp[maxn][];
int pre[maxn][];
char str[maxn];
char ans[maxn];
int main(){
while(cin>>str){
int n=strlen(str);
if(n==){
if((str[]-'')%==) printf("%c\n",str[]);
else printf("-1\n");
continue;
}
memset(pre,-,sizeof(pre));
memset(dp,INF,sizeof(dp));
dp[][]=;
dp[][(str[]-'')%]=;
for(int i=;i<n;i++){
for(int j=;j<;j++){
if(dp[i-][j]+<dp[i][j]){
dp[i][j]=dp[i-][j]+;
pre[i][j]=j;
}
if((str[i]-'')%==){
if(str[i]==''){
if(dp[i-][j]!=i&&dp[i-][j]<dp[i][j]){
dp[i][j]=dp[i-][j];
pre[i][j]=j;
}
}else{
if(dp[i-][j]<dp[i][j]){
dp[i][j]=dp[i-][j];
pre[i][j]=j;
}
}
}
if((str[i]-'')%==&&dp[i-][((j-)%mod+mod)%mod]<dp[i][j]){
dp[i][j]=dp[i-][((j-)%mod+mod)%mod];
pre[i][j]=((j-)%mod+mod)%mod;
}
if((str[i]-'')%==&&dp[i-][((j-)%mod+mod)%mod]<dp[i][j]){
dp[i][j]=dp[i-][((j-)%mod+mod)%mod];
pre[i][j]=((j-)%mod+mod)%mod;
}
}
}
if(dp[n-][]==n){
int flag=;
for(int i=;i<n;i++){
if(str[i]=='') flag=;
}
if(flag==) printf("0\n");
else printf("-1\n");
continue;
}
int cnt=;
int now=n-;
int j=;
while(now>=){
int pree=pre[now][j];
if(dp[now-][pree]==dp[now][j]){
ans[cnt++]=str[now];
}
j=pree;
now--;
if(now==){
if(pree==(str[]-'')%){
ans[cnt++]=str[now];
}
}
}
for(int i=cnt-;i>=;i--){
printf("%c",ans[i]);
}
printf("\n");
}
}
codeforces 792CDivide by Three(两种方法:模拟、动态规划的更多相关文章
- 探讨instanceof实现原理,并用两种方法模拟实现 instanceof
在开始之前先了解下js数据类型 js基本数据类型: null undefined number boolean string js引用数据类型: function object array 一说ins ...
- Loadrunner 接口测试的两种方法
其实无论用那种测试方法,接口测试的原理是通过测试程序模拟客户端向服务器发送请求报文,服务器接收请求报文后对相应的报文做出处理然后再把应答报文发送给客户端,客户端接收应答报文这一个过程. 方法一.用Lo ...
- 安卓ListView操作的两种方法
举例做一个微信的中间部分(好友消息等信息通知) 第一种:BaseAdapter() package com.example.wx; import java.util.ArrayList;import ...
- 在Activity中响应ListView内部按钮的点击事件的两种方法!!!
在Activity中响应ListView内部按钮的点击事件的两种方法 转载:http://www.cnblogs.com/ivan-xu/p/4124967.html 最近交流群里面有人问到一个问题: ...
- 计算理论:NFA转DFA的两种方法
本文将以两种方法实现NFA转DFA,并利用C语言实现. 方法二已利用HNU OJ系统验证,方法一迷之WA,但思路应该是对的,自试方案,测试均通过. (主要是思路,AC均浮云,大概又有什么奇怪的Case ...
- SQL Server中灾难时备份结尾日志(Tail of log)的两种方法
转自:http://www.cnblogs.com/CareySon/archive/2012/02/23/2365006.html SQL Server中灾难时备份结尾日志(Tail of log) ...
- Java 创建线程的两种方法
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- 【java基础 13】两种方法判断hashmap中是否形成环形链表
导读:额,我介绍的这两种方法,有点蠢啊,小打小闹的那种,后来我查了查资料,别人都起了好高大上的名字,不过,本篇博客,我还是用何下下的风格来写.两种方法,一种是丢手绢法,另外一种,是迷路法. 这两种方法 ...
- windows下获取IP地址的两种方法
windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...
- android 之 启动画面的两种方法
现在,当我们打开任意的一个app时,其中的大部分都会显示一个启动界面,展示本公司的logo和当前的版本,有的则直接把广告放到了上面.启动画面的可以分为两种设置方式:一种是两个Activity实现,和一 ...
随机推荐
- PHP json_decode返回null解析失败原因
在PHP5.4之前 json_decode函数有两个参数json_decode有两个参数,第一个是待解析的字符串,第二个是是否解析为Array json_decode要求的字符串比较严格:(1)使用U ...
- (数据科学学习手札18)二次判别分析的原理简介&Python与R实现
上一篇我们介绍了Fisher线性判别分析的原理及实现,而在判别分析中还有一个很重要的分支叫做二次判别,本文就对二次判别进行介绍: 二次判别属于距离判别法中的内容,以两总体距离判别法为例,对总体G1,, ...
- Django的命令操作,python
忘记时候,查看命令用:python manage.py 1 建立项目的命令: django-admin.py startproject project_name 2 在项目的目录下建立app: dja ...
- C++11中default的使用
In C++11, defaulted and deleted functions give you explicit control over whether the special member ...
- 5 多线程 模拟qq聊天
1.多线程思路 使用多线程完成一个全双工的QQ聊天程序 2.版本1:程序小框架 #1.收数据,然后打印 def recvData(): pass #2.检测键盘,发数据 def sendData(): ...
- Linux使用imagemagick的convert命令压缩图片,节省服务器空间
1,安装imagemagick yum install ImageMagick 2,获取图片 find ./ -regex '.*\(jpg\|JPG\|png\|jpeg\)' -size +500 ...
- .netcore centos环境搭建实战
步骤 1. 安装VMware Workstation 下载地址:https://my.vmware.com/cn/web/vmware/info/slug/desktop_end_user_compu ...
- Ubuntu16.04安装Zabbix
基于Zabbix+MySQL+Apache(可选) apt-get install php7.0-bcmath php7.0-xml php7.0-mbstring安装Zabbix所需的几个PHP模块 ...
- Leetcode 672.灯泡开关II
灯泡开关II 现有一个房间,墙上挂有 n 只已经打开的灯泡和 4 个按钮.在进行了 m 次未知操作后,你需要返回这 n 只灯泡可能有多少种不同的状态. 假设这 n 只灯泡被编号为 [1, 2, 3 . ...
- 安装arch系统时,把ubuntu的efi分区格式化
导致无法从grub进入ubuntu,之后我进入win10,把ubuntu的分区都删了. 再重启,只能进入黑色的grub界面,显示 grub>> 甚至无法进入win10.只能通过在开机时按F ...