17年武汉大学网络赛—Divide by Six

2024-05-24 23:38

本文主要是介绍17年武汉大学网络赛—Divide by Six,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接: 点击打开链接


第一篇博客啊...


题目意思大概是这样的,给出一个长为10^5的数,然后让你删掉其中某些数,使其为6的倍数(前缀0也要删去),求删除后所可能保留的最长的。


思路一:(大佬学长说的歪门邪道解法)

       一个数是6的倍数,那么它肯定也是23的倍数。2的倍数很好判断末尾的数可以被2整除,3的倍数:所有位上的数值相加是3的倍数。

       这样的话,就可以控制一个可行区间[l, r]s[l]!= ‘0’, (s[r]-‘0’)%2== 0;),然后在这个区间删除就可以了。

       这样想是正确的,但是又会碰到一系列问题,怎么删...

       sum为该区间所有位上的数值的和,sum%3== 1 || 2 || 0;显然,0是我们想要的结果,如果等于1呢,可以删掉一个122...so on;如果等于2呢,也会有好多种情况。因为369不用考虑(加上或者删除不会影响sum%3的值),就变成了删124578这些数...然后会越想越麻烦,当时在赛场上就是这样陷入脑残的世界。

       大佬给出了此方法的正解,也是他们赛场上的代码(为什么我没想到- -!)...将可行区间内的所有的数都%3,这样这个区间就相当于012三种元素的组合...这样的话,sum%3== 1,只意味着两种情况的删除 11或者22sum%3== 2,删掉一个2或者21

       ok!想到这里再加上对前缀零的删除就可以很完美的a掉了。(不过还要分清一个细节,对区间维护的时候应该是用s[i]来判断,一个粗心wa了一次)


#include <bits/stdc++.h>using namespace std;string s;
int a[100050];int main()
{cin >> s;int ans= -1, pr= 0;for(int i= 0; i< s.length(); i++) { a[i]= (s[i]- '0')% 3; pr+= a[i]; if(s[i]== '0') ans= 1; }int l= 0, r= s.length()- 1;while(s[l]== '0') l++;while(r>= l){if((s[r]- '0')% 2!= 0) { pr-= a[r]; r--; continue; }if(pr% 3== 1){int p= r;while(a[p]!= 1 && p>= l) p--;if(p== l){int ll= l+ 1;while(s[ll]== '0') ll++;ans= max(ans, r- ll+ 1);}else if(p> l) ans= max(ans, r- l);p= r- 1;while(a[p]!= 2 && p> l) p--;if(a[p]== 2){p--;while(a[p]!= 2 && p>= l) p--;if(p== l){int ll= l+ 1;while(s[ll]== '0') ll++;ans= max(ans, r- ll);} else if(p> l) ans= max(ans, r- l- 1);}} else if(pr% 3== 2){int p= r- 1;while(a[p]!= 2 && p>= l) p--;if(p== l){int ll= l+ 1;while(s[ll]== '0') ll++;ans= max(ans, r- ll+ 1);}else if(p> l) ans= max(ans, r- l);p= r- 1;while(a[p]!= 1 && p> l) p--;if(a[p]== 1){p--;while(a[p]!= 1 && p>= l) p--;if(p== l){int ll= l+ 1;while(s[ll]== '0') ll++;ans= max(ans, r- ll);} else if(p> l) ans= max(ans, r- l- 1);}} else ans= max(ans, r- l+ 1);r--;}if(ans== -1) printf("-1s\n"); else printf("%d\n", ans);return 0;
}



思路二:(dp...

       之前没有接触过数位dp,赛场上虽然很努力想用dp解决,但是还是想不到递推关系...赛后看了大佬的代码就傻眼了。

       对整个进行序列逐个删选。

       dp[i][j]:表示取到第i位,余数为j的最优解;(是不是顿时想到了一切......跟背包一样)


       删第i位:dp[i][j]==max(dp[i][j], dp[i- 1][j])


       不删:  dp[i][(j* 10+ a)]== max(dp[i][j* 10+ a],dp[i- 1][j]+);(a为第i位上的数值)


       这样就可以完美解决了。但是还是要注意一下初始化的问题...

#include<bits/stdc++.h>  using namespace std;int f[100050][6];
char s[100050];int main()
{	scanf("%s", s+ 1); int l= strlen(s+ 1), ans= -1;for(int i= 1; i<= l; i++) if(!(s[i]- '0')) ans= 1; //  ???0???ans???1?for(int i= 0; i<= l; i++) for(int j= 0; j< 6; j++) f[i][j]= -100050; // ??? for(int i= 1; i<= l; i++){int a= s[i]- '0';if(a!= 0) f[i][a% 6]= 1;for(int j= 0; j< 6; j++) f[i][j]= max(f[i][j], f[i- 1][j]); // ???i?for(int j= 0; j< 6; j++) f[i][(j* 10+ a)% 6]= max(f[i][(j* 10+ a)% 6], f[i- 1][j]+ 1); // ??i?ans= max(ans, f[i][0]);}if(ans!= -1) printf("%d\n", ans); else printf("-1s\n");return 0;
}






这篇关于17年武汉大学网络赛—Divide by Six的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/999858

相关文章

【Altium】查找PCB上未连接的网络

【更多软件使用问题请点击亿道电子官方网站】 1、文档目标: PCB设计后期检查中找出没有连接的网络 应用场景:PCB设计后期,需要检查是否所有网络都已连接布线。虽然未连接的网络会有飞线显示,但是由于布线后期整板布线密度较高,虚连,断连的网络用肉眼难以轻易发现。用DRC检查也可以找出未连接的网络,如果PCB中DRC问题较多,查找起来就不是很方便。使用PCB Filter面板来达成目的相比DRC

17.用300行代码手写初体验Spring V1.0版本

1.1.课程目标 1、了解看源码最有效的方式,先猜测后验证,不要一开始就去调试代码。 2、浓缩就是精华,用 300行最简洁的代码 提炼Spring的基本设计思想。 3、掌握Spring框架的基本脉络。 1.2.内容定位 1、 具有1年以上的SpringMVC使用经验。 2、 希望深入了解Spring源码的人群,对 Spring有一个整体的宏观感受。 3、 全程手写实现SpringM

通信系统网络架构_2.广域网网络架构

1.概述          通俗来讲,广域网是将分布于相比局域网络更广区域的计算机设备联接起来的网络。广域网由通信子网于资源子网组成。通信子网可以利用公用分组交换网、卫星通信网和无线分组交换网构建,将分布在不同地区的局域网或计算机系统互连起来,实现资源子网的共享。 2.网络组成          广域网属于多级网络,通常由骨干网、分布网、接入网组成。在网络规模较小时,可仅由骨干网和接入网组成

Toolbar+DrawerLayout使用详情结合网络各大神

最近也想搞下toolbar+drawerlayout的使用。结合网络上各大神的杰作,我把大部分的内容效果都完成了遍。现在记录下各个功能效果的实现以及一些细节注意点。 这图弹出两个菜单内容都是仿QQ界面的选项。左边一个是drawerlayout的弹窗。右边是toolbar的popup弹窗。 开始实现步骤详情: 1.创建toolbar布局跟drawerlayout布局 <?xml vers

【Qt6.3 基础教程 17】 Qt布局管理详解:创建直观和响应式UI界面

文章目录 前言布局管理的基础为什么需要布局管理器? 盒布局:水平和垂直排列小部件示例:创建水平盒布局 栅格布局:在网格中对齐小部件示例:创建栅格布局 表单布局:为表单创建标签和字段示例:创建表单布局 调整空间和伸缩性示例:增加弹性空间 总结 前言 当您开始使用Qt设计用户界面(UI)时,理解布局管理是至关重要的。布局管理不仅关系到UI的外观,更直接影响用户交互的体验。本篇博

使用 GoPhish 和 DigitalOcean 进行网络钓鱼

配置环境 数字海洋VPS 我创建的丢弃物被分配了一个 IP 地址68.183.113.176 让我们登录VPS并安装邮件传递代理: ssh root@68.183.113.176apt-get install postfix 后缀配置中的点变量到我们在 DigitalOcean 中分配的 IP:mynetworks nano /etc/postfix/main.cf

Linux网络编程之循环服务器

1.介绍 Linux网络循环服务器是指逐个处理客户端的连接,处理完一个连接后再处理下一个连接,是一个串行处理的方式,比较适合时间服务器,DHCP服务器.对于TCP服务器来说,主要阻塞在accept函数,等待客户端的连接。而对于UDP服务器来说,主要阻塞在recv函数. 2.循环服务器模型 TCP循环服务器: 算法如下:          socket(...);

Linux网络编程之简单并发服务器

1.概念 与前面介绍的循环服务器不同,并发服务器对服务请求并发处理。而循环服务器只能够一个一个的处理客户端的请求,显然效率很低. 并发服务器通过建立多个子进程来实现对请求的并发处理,但是由于不清楚请求客户端的数目,因此很难确定子进程的数目。因此可以动态增加子进程与事先分配的子进程相结合的方法来实现并发服务器。 2. 算法流程 (1)TCP简单并发服务器:     服务器子进程1:

Android 扇形网络控件 - 无网络视图(动画)

前言 一般在APP没有网络的情况下,我们都会用一个无网络的提示图标,在提示方面为了统一app的情况,我们一般使用简单的提示图标,偶尔只需要改变一下图标的颜色就一举两得,而不需要让PS来换一次颜色。当然app有图标特殊要求的就另当别论了。 效果图 当你第一眼看到这样的图,二话不说直接让UI给你切一张图标来的快对吧,我其实开始也是这么想的,但是到了做的app越来越多的时候,你就会发现就算是用

poj 2391 Ombrophobic Bovines (网络流)

这是一道很经典的网络流的题目。首先我们考虑假如我们的时间为无穷大。我们吧每个点拆成2个点 i和i' .。虚拟源点s和汇点t。对于每个点建边(s,i, a[i])  (i‘,t,ib[i]) 。 其中a[i]为给点有多少牛,b[i]为容量。i和j连通 建边 (i,j',inf);如果最大流==所有牛的个数,就可能装下所有的牛。那么现在我们考虑时间。假设最大时间为T.那么如果i到j的的最短时间>T