LA2965侏罗纪(异或和为0的最大数字个数)
题意:
给你n个字符串,让你在里面找到一个字符串集合使得这些字符串中所有的字母出现的次数和为偶数,输出集合的最大个数,和ASCII最小的解。
思路:
考虑到每个字符串中所有的字符都是有大写字母组成的,我们可以把每个字符串都用一个26位长的二进制数表示,比如第一位表示A,那么当第一位为0的时候就是说明A出现了偶数次,1表示出现了奇数次(直接异或),那么我们要找到满足题意的集合也就是可以转化成我们在n个26位长的二进制数中找到最多的数字,使得他们异或一起最后等于0(等于0表示所有的字母都是偶数次),这样我们有两种方式,一种是我自己写的暴搜,时间复杂度O(2^n)没有超时,如果是要完全的暴力建议去写搜索,不要写for循环枚举,因为for的枚举在判断的时候时间复杂度还要*n,这样估计就超时了,写搜索可以在状态转换的时候把值算出来,这样最后的时候不用可以去算什么,直接if判断,减少了一个n,时间复杂度应该是妥妥的O(2^n),还有就是再说下白书上的方法,用的是中途相遇法,这个方法感觉很好,让我想起了双向广搜,这个题目我想是不是应该叫双向深搜,大体思路就是把要枚举的东西分成两部分分别枚举,然后在结合一起去判断,时间复杂度可以降低不少,白书给的时间复杂度我感觉算的有问题,我算的是O(1.44^n*n/2),两个方法我都试了,中途相遇法的时间复杂度优化了很多,下面是两个方法的AC代码。
直接暴力深搜 时间复杂度
O(2^n) runtime 2.292
#include<map>
#include<string>
#include<stdio.h>
#include<string.h>
using namespace std;
int num[30];
char str[1100];
int Ans ,Anszt;
void DFS(int nowid ,int nows ,int nownum ,int nowzt)
{
if(nowid == 0)
{
if(nownum == 0)
{
if(Ans <= nows)
{
Ans = nows;
Anszt = nowzt;
}
}
return ;
}
DFS(nowid - 1 ,nows ,nownum ,nowzt * 2);
DFS(nowid - 1 ,nows + 1 ,nownum ^ num[nowid] ,nowzt * 2 + 1);
}
int main ()
{
int n ,i ,j ,now;
while(~scanf("%d" ,&n))
{
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
now = 0;
int l = strlen(str) - 1;
for(j = 0 ;j <= l ;j ++)
now = now ^ (1 << (str[j] - 'A'));
num[i] = now;
}
Ans = Anszt = 0;
DFS(n ,0 ,0 ,0);
printf("%d\n" ,Ans);
int nowid = 1 ,mk = 0;
while(Anszt)
{
if(Anszt&1)
{
if(mk) printf(" %d" ,nowid);
else printf("%d" ,nowid);
mk = 1;
}
Anszt /= 2;
nowid ++;
}
printf("\n");
}
return 0;
}
中途相遇法 时间复杂度
O(2^(n/2)*n/2) => 1.44^n*n/2 runtime 0.029
#include<map>
#include<string>
#include<stdio.h>
#include<string.h>
using namespace std;
map<int ,int>mark;
int num[30];
char str[1100];
int bitcount(int x)
{
return x == 0 ? 0 : bitcount(x / 2) + (x & 1);
}
int main ()
{
int n ,i ,j ,now ,l;
while(~scanf("%d" ,&n))
{
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
now = 0 ,l = strlen(str) - 1;
for(j = 0 ;j <= l ;j ++)
now = now ^ (1 << (str[j] - 'A'));
num[i] = now;
}
mark.clear();
int n1 = n / 2;
int n2 = n - n1;
for(i = 0 ;i < (1 << n1) ;i ++)
{
int x = 0;
for(j = 1 ;j <= n1 ;j ++)
if(i & (1 << (j-1))) x ^= num[j];
if(!mark.count(x) || bitcount(i) > bitcount(mark[x]))
mark[x] = i;
}
int Ans = 0;
for(i = 0 ;i < (1<<n2) ;i ++)
{
int x = 0;
for(j = 1 ;j <= n2 ;j ++)
if(i & (1 << (j-1))) x ^= num[n1 + j];
if(mark.count(x) && bitcount(i) + bitcount(mark[x]) > bitcount(Ans))
Ans = (i << n1) ^ mark[x];
}
printf("%d\n" ,bitcount(Ans));
int mk = 0,Anszt = Ans ,nowid = 1;
while(Anszt)
{
if(Anszt&1)
{
if(mk) printf(" %d" ,nowid);
else printf("%d" ,nowid);
mk = 1;
}
Anszt /= 2;
nowid ++;
}
printf("\n");
}
return 0;
}
LA2965侏罗纪(异或和为0的最大数字个数)的更多相关文章
- LA2965 n个数中选出最多个数异或和为0
intput n 1<=n<=24 n串只有大写字母的字符串 output 选出最多个字符串且每个大写字母出现的次数为偶数 第一行输出个数x 第二行输出x个字符串的下标 做法:将每个字符串 ...
- 0..n去掉一个数,给你剩下的数,找出去掉的那个数
转载请注明转自blog.csdn.net/souldak , 微博@evagle 首先,考虑没有去掉那些数,如果n是奇数,n+1个最低位肯定是0101...01,count(0)=count(1),如 ...
- 在0~N个数字中,取指定个数的不重复数字,要求这些数字的和为指定值,求所有结果
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- TabIndex 属性 Tabindex="-1" 与Tabindex="0"、任意数字 (收录)
TabIndex 属性 Tabindex="-1" 与Tabindex="0".任意数字 html中的tabIndex属性可以设置键盘中的TAB键在控件中的移动 ...
- GridView导出成Excel字符"0"丢失/数字丢失的处理方式 收藏
GridView导出成Excel字符"0"丢失/数字丢失的处理方式 收藏 GridView 导出成Excel文件,这个代码在网上比较多.但是发现存在一个问题,导出的数据中如果有&q ...
- 获取数组中多个相加等于0的一组数字 javascript
//获取数组中两个相加等于0的一对数字,比如[ [ -10, 10 ], [ -5, 5 ] ] var arr=[-5,10,1,-10,3,4,5,9] //对数组进行排序 arr.sort(fu ...
- Easyui的numberbox无法输入以0开头的数字编号(转载)
1.问题 项目中碰到这样一个问题,Easyui的numberbox在输入数字编号的时候不能以0开头 在我输入以0开头的数字编号后,离开输入框的时候,那个前缀0就自动去掉了. 接下来,我们查看API说明 ...
- x^a=b(mod c)求解x在[0,c-1]上解的个数模板+原根求法
/************************************* 求解x^a=b(mod c) x在[0,c-1]上解的个数模板 输入:1e9>=a,b>=1,1e9>= ...
- python计算1~2008中0和1的个数
计算1~2008中所有自然数中1和0的个数总数. 通过自然数的大小划分区间,将自然数每位上的数载入列表,循环计数. list = [] onecount = 0 zerocount = 0 for i ...
随机推荐
- 剑指 Offer 63. 股票的最大利润 + 动态规划
剑指 Offer 63. 股票的最大利润 Offer_63 题目描述 方法一:暴力法 package com.walegarrett.offer; /** * @Author WaleGarrett ...
- bouncycastle中添加HMAC-SM3支持
一. 最近看完了PKCS#5中的内容,总结一下自己添加HMAC-SM3中遇到的问题和解决方法. 大概通读BC java源码以后,开始上手修改. 在SM3.java中添加如下代码: /** * SM3 ...
- 鸿蒙的js开发模式19:鸿蒙手机下载python服务器端文件的实现
目录:1.承接上篇鸿蒙客户端上传文件2.域名通过内网穿透工具3.python服务器端代码4.鸿蒙手机的界面和业务逻辑5.<鸿蒙的js开发模式>系列文章合集 1.承接上篇鸿蒙客户端上传文件, ...
- SpringMVC执行流程及源码分析
SpringMVC流程及源码分析 前言 学了一遍SpringMVC以后,想着做一个总结,复习一下.复习写下面的总结的时候才发现,其实自己学的并不彻底.牢固.也没有学全,视频跟书本是要结合起来一起, ...
- 【RocketMQ源码分析】深入消息存储(1)
最近在学习RocketMQ相关的东西,在学习之余沉淀几篇笔记. RocketMQ有很多值得关注的设计点,消息发送.消息消费.路由中心NameServer.消息过滤.消息存储.主从同步.事务消息等等. ...
- .zip爆破
.zip爆破 Python的优化问题 Python在计算密集型任务方面没有明显的多线程优化,多线程更加适合用于处理I/O密集型任务(如网络请求).爆破任务使用顺序执行即可. 编写Python脚本 一个 ...
- POJ_2065 SETI 【同余高斯消元】
一.题目 SETI 二.分析 给定一个模数,一串字符串,字符串长度为N,相当于是N个方程的答案,而这N个方程中有N个未知数,要求的就是这N个未知数的值,很显然的高斯消元,遇到模数和除法,用逆元就好. ...
- 网易云信 QUIC 加速服务架构与实践
导语:网易云信作为音视频服务提供商的领导者,一直致力于提供顶级的音视频通话服务体验,为用户在各种恶劣环境下提供可靠的音视频服务.如何在极端弱网条件下仍然能给用户提供可靠的音视频服务,是网易云信关注的重 ...
- 12、MyBatis教程之缓存
13.缓存 简介 1.什么是缓存 [ Cache ]? 存在内存中的临时数据. 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高 ...
- Logback简介及配置文件logback.xml详解
logback简介及配置文件说明 @author:wangyq @date:2021年3月31日 logback简介 Logback是由log4j创始人设计的另一个开源日志组件,官方网站: htt ...