CHD2017校赛题解
来源:互联网 发布:php 根据ip 查询地区 编辑:程序博客网 时间:2024/05/21 02:49
B. Boy and Girls
题目链接
题意:给一串含有n个Gn个B的字符串, 交换相邻字符,使字符串达到GBGBGB / BGBGBG,求最小交换次数;
解法:暴力扫字符串,出现不满足条件的情况,就在后边找到相应的字符。O(n^2)绝对超时;因此,不能扫。换一个思路,从末状态开始入手,每一个B/G都要到达位置1,3,5,7,9 / 2,4,6,8,10,而将一个字符从位置x1移动到x2,需要交换|x1-x2|次,因此只需计算|x1-1|+|x2-3|+|x3-5|+...+|xn-2*n+1|和|x1-2|+|x2-4|+|x3-6|+...+|xn-2*n|,取最大值即可
#include <cstdio>#include<queue>#include<cstdlib>#define ll long longusing namespace std;ll T,n;char s[200005];queue<ll> q;int main(){ scanf("%lld",&T); while(T--) { scanf("%lld",&n); scanf(" %s",s); for(int i=0;i<2*n;i++) { if(s[i]=='B') { q.push(i); } } ll k1=0,k2=1,sum1=0,sum2=0; while(!q.empty()) { ll x=q.front(); q.pop(); sum1+=abs(k1-x); sum2+=abs(k2-x); k1+=2; k2+=2; } printf("%lld\n",min(sum1,sum2)); } return 0;}
E.Colorful Ribbon
题目链接
题目类型:dp
题意:将给定只包含小写字符的字符串,分为没有重复的几段,问有多少种分法
解法:dp[i]表示前i个字符可以分为几段,转移方程为dp{i}=sum(dp[k]) (k = p ~ i-1 ),p表示当前串,上一个断点能取到的中,最靠前的那个字符的位置
#include <iostream>#include<stdio.h>#include<cstring>#include<algorithm>#define ll long longusing namespace std;const int inf=0x3f3f3f3f3f3f;int T,vist[30],p;ll dp[100005];char s[100005];const ll MOD = 1000000000+7;int main(){ scanf("%d",&T); while(T--) { memset(s,0,sizeof(s)); scanf(" %s",s+1); memset(dp,0,sizeof(dp)); int len = strlen(s+1); memset(vist,0,sizeof(vist)); dp[0]=1; p=-1; for(int i=1;i<=len;i++) { p=max(vist[s[i]-'a'],p); for(int j=p;j<i;j++) { dp[i]+=(dp[j]%MOD); } vist[s[i]-'a']=i; } cout << dp[len]%MOD << endl; } return 0;}
J.Repeated String
题目链接
题意:构造长度为n的B,使得与A的distance最小;
题解:暴力枚举a-z,判断每一位的B上的字母应该是什么。O(26*n*m)
Code:(不知道为啥RE,然后又TE,以后知道哪错了,就补代码)
L.QAQ Number
题目链接
题意:计算出指定范围内,符合条件的数字的个数
题解:现场想法是利用10^0-10^3有90个,10^6-10^9有90个.....10^15-10^18有90个,将完全包含的区间加上去,左右边界单独处理,处理时发现,右边界数量级很大,不能个暴力,然后队友想了个判断方法,异常难写啊。。。最后,这写法估计要代码200+。。。放弃了。下场才知道,这个神奇做法。
因为,通过检测方法实现数量很大,所以说明在给定范围的答案不多,因此直接从答案入手,枚举Q,B即可,可以利用;有个小问题:就是B为0的时候,方法1。特判B为0,00,000...时,方法2,vist[]标记这个数是否被访问过;
#include <cstdio>#include<queue>#include<cstdlib>#define ll long longusing namespace std;ll T,n;char s[200005];queue<ll> q;int main(){ scanf("%lld",&T); while(T--) { scanf("%lld",&n); scanf(" %s",s); for(int i=0;i<2*n;i++) { if(s[i]=='B') { q.push(i); } } ll k1=0,k2=1,sum1=0,sum2=0; while(!q.empty()) { ll x=q.front(); q.pop(); sum1+=abs(k1-x); sum2+=abs(k2-x); k1+=2; k2+=2; } printf("%lld\n",min(sum1,sum2)); } return 0;}
- CHD2017校赛题解
- 【题解】2016.5.8SWJTU校赛题解
- 2017校赛题解
- zju 2007校赛题解
- 西工大ACM校赛题解
- NJUST校赛部分题解
- gdut校赛决赛题解
- 校赛反思和题解
- ACM校赛网络赛部分题解
- 校赛网络赛部分题解
- 安徽大学第四届ACM校赛题解
- 北航校赛2014 预赛 题解
- 北航校赛2014 决赛 题解
- 2015.12 hdu 校赛简易题解
- 2016.4.17 南理工校赛题解
- 十四届北师大校赛题解
- 2017gdut校赛初赛题解
- 2017gdut校赛决赛题解
- 思
- 倒排索引
- 链表翻转的迭代和递归解法
- HTTP 1.1与HTTP 1.0的比较
- select查询语句
- CHD2017校赛题解
- django TemplateDoesNotExist at /
- Windows MongoDB 安装及配置
- Svn版本管理
- makefile--葵花宝典
- keil MDK 安装单片机库文件
- win10 uwp 修改Pivot Header 颜色
- 3443
- python基础学习之文件操作