战争游戏

战争游戏的至关重要环节就要到来了,这次的结果将决定王国的生死存亡,小B负责首都的防卫工作。首都处于一个四面环山的盆地中,周围的n个小山构成一个环,作为预警措施,小B计划在每个小山上设置一个观察哨,日夜不停的瞭望周围发生的情况。
一旦发生外敌入侵事件,山顶上的岗哨将点燃烽烟。若两个岗哨所在的山峰之间没有更高的山峰遮挡且两者之间有相连通路,则岗哨可以观察到另一个山峰上的烽烟是否点燃。由于小山处于环上,任意两个小山之间存在两个不同的连接通路。满足上述不遮挡的条件下,一座山峰上岗哨点燃的烽烟至少可以通过一条通路被另一端观察到。对于任意相邻的岗哨,一端的岗哨一定可以发现一端点燃的烽烟。
小B设计的这种保卫方案的一个重要特性是能够观测到对方烽烟的岗哨对的数量,她希望你能够帮她解决这个问题。
输入
输入中有多组测试数据。每组测试数据的第一行为一个整数n(3<=n <=10^6),为首都周围的小山数量,第二行为n个整数,依次表示小山的高度h,(1<=h<=10^9)。
输出
对每组测试数据,在单独的一行中输出能相互观察到的岗哨的对数。

样例输入
5
1 2 4 5 3
样例输出
7

分析:首先相邻的两个山峰一定可以相互看到,这里有n对,不相邻的山峰是否可以相互望见取决于这两座山峰之间是否有比这两座山峰更高的山,如果没有,则可以相互望见;如果有,则无法相互望见。由于是可以望见的山峰是成对出现的,所以在计算的时候只要按照一个方向(如逆时针)去寻找,就可以避开重复计数。

思路:设两层循环,第一层循环时节点i从0到n-1,第二层是节点j=(i+2)%n到i-1,是寻找与第一层循环中可以相互望见的山峰。第二层循环中实现主要是看是否有比i和j高的山峰,刚开始的时候,i和j只隔一座山,只要判断这座山与i和j的高度就可以了。如果i和j可以相互望见,则j=j+1,这时中间隔了两座山峰,此时哟更新两者之间最高的山峰。以此类推,直到结束循环。

由于环图,所以在计算的时候需要对n取余。

#include "stdafx.h"
#include <iostream>
#include<vector>
using namespace std;
int main()
{
    //存放山的个数
    long long n;
    //缓存输入的每个山头的高度
    long long x;
    //存放各个山头的高度
    vector<int> mon;
    //能够观测到对方烽烟的岗哨对的数量
    long long sum=0;
	//两座山峰之间最高的山
    long long max; 
     
    while(cin>>n)
    {
        for(int i=0;i<n;i++)//用来接收各个山顶的高度
        {
            cin>>x;
            mon.push_back(x);
        }
        sum=n;
        //山峰i
        for(int i=0;i<n;i++)
        {
            //山峰j
			max=mon[(i+1)%n];//当两座山峰之间只有一座山时,max则是这座山峰
            for(int j=(i+2)%n;j!=((i-1+n)%n);j=(++j)%n)
			//如果for循环里边最后写(++j)%n会出错
            {
                //判断i和j之间是否有比他俩高的山峰
                if((max<mon[i])&&(max<mon[j]))
                    sum=sum+1;

				//更新两个山峰之间的最高的山峰 
				if(mon[j]>max)
					max=mon[j];
				
            }
        }
        cout<<sum;
    }
    system("pause");
}