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实现,和一 ...
随机推荐
- python2.7练习小例子(二十五)
25):题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁.问第4个人岁数,他说比第3个人大2岁.问第三个人,又说比第2人大两岁.问第2个人,说比第一个人大两岁.最后问第一个人,他 ...
- 58HouseSearch项目迁移到asp.net core
前言 58HouseSearch这个项目原本是基于ASP.NET MVC 4写的,开发环境是Windows+VS2015,发布平台是linux+mono+jexus,这样看来整个项目基本已经满足跨平台 ...
- nginx https ssl 配置
#设置https 访问server { listen ; server_name www.xxx.com; access_log xxx/xxx/xxx.log combined; index ind ...
- 3,SQL语句及数据库优化
1,统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的. 所以封装成复用方法,用标准模板来控制. select*from dual select*Fr ...
- Qt 在Label上面绘制罗盘
自己写的一个小小的电子罗盘的一个小程序,不过是项目的一部分,只可以贴绘制部分代码 效果如下图 首先开始自己写的时候,虽然知道Qt 的坐标系是从左上角开始的,所以,使用了算法,在绘制后,在移动回来,但是 ...
- Python 基本文件操作
文件模式 'r' 读模式 'w' 写模式 (清除掉旧有数据并重新开始) 'a' 追加模式 'b' 二进制模式 '+' 读/写模式 注意: 'b' : 二进制模式 可添加到其他模式中使用 '+' ...
- 牛客网暑期ACM多校训练营(第七场):J-Sudoku Subrectangles
链接:J-Sudoku Subrectangles 题意:给出 n * m 的字母矩阵,公52种字母.求出不含重复元素的子矩阵的个数. 题解: L[i][j]:s[i][j] ~ s[i][ j - ...
- MySQL统计数据库表大小
use information_schema; SELECT TABLE_NAME, (DATA_LENGTH/1024/1024) as DataM , (INDEX_LENGTH/1024/102 ...
- RDL/RDLC批量单据打印
使用RDL或RDLC进行单据打印时,单张单据打印比较直观简单,无需说明.下面我们来谈一下批量单据打印的实现方法.以下以RDL的ReportBuilder设计环境为例进行讲解,RDLC.VS设计环境同理 ...
- [leetcode-651-4 Keys Keyboard]
Imagine you have a special keyboard with the following keys: Key 1: (A): Prints one 'A' on screen. K ...