codeforces #307 B. ZgukistringZ(枚举+计数)
2015-06-21 01:25
369 查看
题目链接:
卖萌的链接
题目大意:
给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为子串不重叠且出现次数最多的串
题目分析:
其实就是对A,B,C进行计数,判断A中的各个字母的个数分别能分给几个B和几个C,枚举B的个数,计算C的个数,然后取最大值即可,记录去最大值情况下B出现的次数和C出现的次数然后先把B,C输出对应次数,然后把剩下的字符输出出去就好了。比较恶心的是,这道题竟然卡常数,真的在卡常数,所以要进行一个小的剪枝,也就是先求出B出现的最大次数,也就是A全部转成B的情况下B的个数,优化效果出奇的好,但并不是证明优化效果,复杂度怎么算都是26*o(n)
代码如下:
卖萌的链接
题目大意:
给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为子串不重叠且出现次数最多的串
题目分析:
其实就是对A,B,C进行计数,判断A中的各个字母的个数分别能分给几个B和几个C,枚举B的个数,计算C的个数,然后取最大值即可,记录去最大值情况下B出现的次数和C出现的次数然后先把B,C输出对应次数,然后把剩下的字符输出出去就好了。比较恶心的是,这道题竟然卡常数,真的在卡常数,所以要进行一个小的剪枝,也就是先求出B出现的最大次数,也就是A全部转成B的情况下B的个数,优化效果出奇的好,但并不是证明优化效果,复杂度怎么算都是26*o(n)
代码如下:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #define MAX 100007 int num1[50]; int num2[50]; int num3[50]; int num[50]; char s1[MAX]; char s2[MAX]; char s3[MAX]; using namespace std; void scan ( char s[] ) { char ch; ch = getchar (); int i = 0; while ( true ) { if ( ch == ' ' || ch == '\r' || ch == '\n' ) break; s[i++] = ch; ch = getchar(); } s[i] = 0; } void print ( char s[] ) { int i = 0; while ( s[i] ) putchar ( s[i++] ); } int main ( ) { //while ( true ) //{ scan ( s1 ); memset ( num1 , 0 , sizeof ( num1 ) ); memset ( num2 , 0 , sizeof ( num2 ) ); memset ( num3 , 0 , sizeof ( num3 ) ); //scanf ( "%s" , s2 ); scan ( s2 ); //scanf ( "%s" , s3 ); scan ( s3 ); int len = strlen(s1); for ( int i = 0 ; i < len ; i++ ) num1[s1[i]-97]++; len = strlen(s2); for ( int i = 0 ; i < len ; i++ ) num2[s2[i]-97]++; len = strlen(s3); for ( int i = 0 ; i < len ; i++ ) num3[s3[i]-97]++; int ans = 0; int sum1 = MAX , sum2 = MAX; for ( int i = 0 ; i < 26 ; i++ ) if ( num2[i] ) sum1 = min ( sum1 , num1[i]/num2[i] ); for ( int i = 0 ; i < 26 ; i++ ) if ( num3[i] ) sum2 = min ( sum2 , num1[i]/num3[i] ); int index = sum1; sum1 = sum2 = 0; for ( int i = 0 ; i <= index ; i++ ) { bool flag = false; for ( int j = 0 ; j < 26 ; j++ ) { num[j] = num1[j] - num2[j]*i; if ( num[j] < 0 ) { flag = true; break; } } if ( flag ) continue; int temp = MAX; for ( int j = 0 ; j < 26 ; j++ ) if ( num3[j] ) temp = min ( temp , num[j]/num3[j] ); if ( temp + i > ans ) { ans = temp + i; sum1 = i; sum2 = temp; } } if ( ans = 0 ) print(s1); else { for ( int i = 0 ; i < sum1 ; i++ ) //printf ( "%s" , s2 ); print(s2); for ( int i = 0 ; i < sum2 ; i++ ) //printf ( "%s" , s3 ); print(s3); for ( int i = 0 ; i < 26 ; i++ ) num1[i] -= sum1*num2[i] + sum2*num3[i]; for ( int i = 0 ; i < 26 ; i++ ) while ( num1[i]-- ) //printf ( "%c" , 'a'+i ); putchar((char)('a'+i)); puts (""); } //} }
相关文章推荐
- java笔记27 编码表与编码转换
- PB 数据窗口打印详细控制代码
- codeforces #307 C. GukiZ hates Boxes(贪心+二分)
- HDU1052Tian Ji -- The Horse Racing(贪心)
- Linux_4.1_进程控制理论
- 运行及总结
- C#—泛型
- struts搭建基本配置
- Functional MRI (second edition) -- 2. MRI Scanners
- UVa455 Periodic Strings
- java笔记26 IO流其他对象
- 【MVC】ASP.NET MVC 4项目模板的结构简介
- Python_09-面向对象编程
- 实现了一个百度首页的彩蛋——CSS3 Animation简介
- Android界面默认让文本框失去焦点
- tableView的刷新
- MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
- 排版问题,div nav 里面包含的内容没有在其范围内
- hdu 2923 map+Floyd 拉破车
- Redis服务部署