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实现,和一 ...
随机推荐
- ctf题目writeup(9)
继续刷题,找到一个 什么 蓝鲸安全的ctf平台 地址:http://whalectf.xin/challenges (话说这些ctf平台长得好像) 1. 放到converter试一下: 在用十六进制转 ...
- C语言实例解析精粹学习笔记——39(简单的文本编辑器)
实例说明: 编辑一个简单的单行文本编辑器,编辑命令有以下几种:(E.Q.R.I.D) 只有自己在完全空白的情况下编写出来的程序,才是真正自己会的程序,现在所做的,不过是程序的搬运工,把书上的程序搬到网 ...
- YSZOJ:#247. [福利]可持久化线段树 (最适合可持久化线段树入门)
题目链接:https://syzoj.com/problem/247 解题心得: 可持久化线段树其实就是一个线段树功能的加强版,加强在哪里呢?那就是如果一颗普通的线段树多次修改之后还能知道最开始的线段 ...
- CSS3实现加载数据动画2
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Mac OS下搭建Hadoop + Spark集群
首先注意版本兼容问题!!!本文采用的是Scala 2.11.8 + Hadoop 2.7.5 + Spark 2.2.0 请在下载Spark时务必看清对应的Scala和Hadoop版本! 一.配置JD ...
- laravel读excel
fileName = "test.xls";$filePath = "../storage/app/";Excel::load($filePath.$fileN ...
- 「日常训练」Common Subexpression Elimination(UVa-12219)
今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...
- 6.爬虫 requests库讲解 总结
requests库的总结: 用ProcessOn根据前面的几节内容做了个思维导图:
- Eureka搭建
Eureka搭建 一.Eureka基本框架搭建 pom.xml文件配置:主要是引入Eureka所依赖的jar包 <?xml version="1.0" encoding=&q ...
- C++STL——队列
一.相关定义 原理:queue 队列也是一个线性存储表,元素数据的插入在表的一端进行,在另一端删除,从而构成了一个先进先出FIFO(First In First Out)表. 队头&队尾:插入 ...