2014 Super Training #1 C Ice-sugar Gourd 模拟,扫描线
原题 HDU 3363 http://acm.hdu.edu.cn/showproblem.php?pid=3363
给你一个串,串中有H跟T两种字符,然后切任意刀,使得能把H跟T各自分为原来的一半。
解法: 把串想象成一个环,只要满足H跟T都为偶数个,那么就可以做一条过圆心的直线把H跟T平分掉,过直线,只要考虑平分H或者T中的一个就可以了,因为直线本来就把环平分,而此时平分了H或者T,那么剩下的那个也是平分掉的。
具体证明: http://hi.baidu.com/superlong/item/fa552253eb9b71c09f266703
类似于维护这样一条扫描线:
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 100007 char ss[N]; int main() { int len,ka,kb,i,j; int h,t,H,T; while(scanf("%d",&len)!=EOF && len) { scanf("%s",ss); H = T = 0; for(i=0;i<len;i++) { if(ss[i] == 'H') H++; else T++; } if(H%2 || T%2) { puts("-1"); continue; } int mid = len/2; h = t = 0; for(i=0;i<mid;i++) { if(ss[i] == 'H') h++; else t++; } if(h == H/2 && t == T/2) { puts("1"); printf("%d\n",mid); continue; } ka = 0; //尾端 kb = mid; //前端 int flag = 0; while(ka < mid-1) { if(ss[ka] == 'H') //尾端扫出去的字母 h--; else t--; if(ss[kb] == 'H') //前端扫进来的字母 h++; else t++; ka++,kb++; //转 if(h == H/2 && t == T/2) { flag = 1; break; } } if(flag) { puts("2"); printf("%d %d\n",ka,kb); } else puts("-1"); } return 0; }
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com