题目描述
N个新兵站在警官前面,警官要求向左转,一些士兵向左转,一些向右转了。在这一刻,当一些士兵能看到另一个士兵的脸时,就知道弄错了,然后大家同时又转过去,这都是同时发生的,即每两个碰脸的士兵都是同时发现,而且同时又转过去的。这个过程不断地持续,直到队伍稳定下来。请编程找出这些情况(两个人碰脸,转身)发生了多少次。假如这个过程无穷尽,则输出“NO”。
Formation | Comments | Number of turns |
> > < < > < | Initial formation 初始的队伍 | 2 |
> < > < < > | One second has passed 1秒过后 | 2 |
< > < > < > | Two seconds have passed 2秒过后 | 2 |
< < > < > > | Three seconds have passed 3秒过后 | 1 |
< < < > > > | Final formation 最终的队列 | Total: 7 |
输入数据
输入的首行为N(士兵数),其余为符号“>”“ < ”以及回车换行符,总共有N个“< ”“>”符号。每一行可能等于255个字符
1 <= N <= 500000
输出数据
输出次数或“NO”
样例输入
6
>><<><
样例输出
7
正法:
转化为求逆序对,对字符串进行二分,求逆序对数目
这里有一个极其阴险的方法......
规律:不论初始状态如何,最终的状态一定是最左端是<,最右端是.>,所以不会出现无解,因此,有时间复杂度为0(n)算法,只需扫一遍,<左端不能出现>,>的右端不能出现<,答案就是每个<左端的>数之和或每个>右端的<数之和。代码与二分求解相比极其精炼。
总结:对于一些和数学有关的模拟题,数论题,要多去研究,这道题目是否隐藏着什么数学规律
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
Code:
program soldiers;
var s:ansistring;
i,j,k2,n:longint;
ans:int64;
begin
assign(input,'soldiers.in'); reset(input);
assign(output,'soldiers.out'); rewrite(output);
readln(n);
readln(s);
for i:=1 to n do
begin
if s[i]='<' then
inc(ans,k2);
if s[i]='>' then
inc(k2);
end;
writeln(ans);
close(input);
close(output);
end.