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实现,和一 ...
随机推荐
- ecshop漏洞修复 以及如何加固ecshop网站安全?
由于8月份的ECSHOP通杀漏洞被国内安全厂商爆出后,众多使用ecshop程序源码的用户大面积的受到了网站被篡改,最明显的就是外贸站点被跳转到一些仿冒的网站上去,导致在谷歌的用户订单量迅速下降,从百度 ...
- 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(五):测试项目
基于Ubuntu Server 16.04 LTS版本安装和部署Django之(一):安装Python3-pip和Django 基于Ubuntu Server 16.04 LTS版本安装和部署Djan ...
- Git 查看远程分支、本地分支、删除本地分支及远程分支
1. 删除本地分支: git branch -d branchName 2. 删除远程分支: // 方法一:将删除的本地分支推到远程(要删除的远程分支在本地有映射) git push origin : ...
- Mybatis快速入门指南
简介 当下越来越多的企业项目架构中,在持久层部分,抛弃了Hibernate框架,而选用Mybatis框架取而代之,旨在更加深入细致的控制和数据库的交互. MyBatis 本是apache的一个开源项目 ...
- 「个人训练」Can you solve this equation?(HDU-2199)
题意与分析 纯粹水题.本来想做下放松心情的,结果还是被坑了qaq 重点就是在浮点误差.比较左右的下次就直接上1e-10,别看着题目说1e-4然后给个-5,结果暴wa.气傻了..... 代码 #incl ...
- Qt Creater 制作汽车仪表盘
最近项目用到了模拟仪表,网上下载大神编写的按个仪表Meter没有成功 转战 QWt 编译后,在creater中仍然无法使用,只可以在代码中使用 百度说是我编译的版本不对 扔到 开始做自己的 这个用到了 ...
- Linux-获得命令帮助man
date:显示当前系统时间,修改时间 clock,hwclock:显示硬件时间 cal:calendar,查看日历 计时器靠晶体振荡器来完成计时 Linux: 实时时钟,rtc,real time c ...
- mysql字段名与关键字重复解决办法
mysql 关键字与字段名相同,插入或者修改里会报错 解决办法: 1.改字段名,如果库里面表结构关系不复杂,修改字段名就解决 2.在插入或者修改字段时,字段名加上 ` 包上,注意:这里不是引号,是英 ...
- 并查集——poj2492(带权并查集入门)
一.题目回顾 题目链接:传送门 题意:给定n只虫子,不同性别的可以在一起,相同性别的不能在一起.给你m对虫子,判断中间有没有同性别在一起的. 二.解题思路 种类并查集 和poj1073的本质一样 详见 ...
- C++STL——set
一.相关定义 set 集合,有唯一性,即每一个元素只有一个: 是一个有序的容器,里面的元素都是排序好的: 支持插入,删除,查找等操作. 注意 set中的元素可以是任意类型的,但是由于需要排序,所以元素 ...