M - Last Man Standing(Gym - 101341M)

M - Last Man Standing

题目描述

A company of n friends decided to play a multiplayer shooter in the Last Man Standing mode. The distinctive feature of this mode is when a player is killed, he does not respawn, but waits a round to finish. A round finishes when there is only one player alive.

You are given a notarized screenshot of the current fight results, made during the first round of the game. It provides an information about how many kills each player has made. You want to check if it's a fake or not, i.e. whether such situation could occur during the game.

Input

The first line contains a single integer n (1 ≤ n ≤ 200000) — the number of players.

The second line contains n integers ai separated by a space (0 ≤ ai ≤ 109) — the numbers of kills made by each player. These numbers are given in non-increasing order.

Output

If such situation was not possible in the game, output «NO» (without quotes).

Otherwise, in the first line output «YES» (without quotes), and then output a log of kills in the round, consisting of k pairs of integers, where k is the total number of kills made at the moment of taking the screenshot. Each pair of integers in the log must consist of the number of the player who made the kill, and the number of the killed player, exactly in this order. Records in the log must be ordered chronologically. If there are several correct logs, output any of them.

Examples
Input

5
2 1 1 0 0

Output

YES
3 5
2 4
1 3
1 2

Input

7
3 2 2 0 0 0 0

Output

NO

Input

1
0

Output

YES

Input

3
1 0 0

Output

YES
1 3

题目大意

题意:
有n个人玩了一局枪战游戏,这个游戏的特点是在一局中死亡后不能复活,当只有一个人活着时间到了的时候游戏结束(有点类似个人竞技)。
下面给你n和每个人的杀敌数量,让你判断符不符合事实,如果符合输出他们先后杀敌的次序。
思路:首先总杀敌数肯定不能大于等于人数,杀敌数符合的从后往前找,让后面的人尽量杀靠后的人,然后依次向前遍历,记录一下遍历的位置,不然超时。

AC代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
int x,f;//x为杀敌数,f表示有没有被杀
}a[200010];
int main()
{
    int n;
    scanf("%d",&n);
    ll sum=0;
    for(int i=0; i<n; i++)
    {
        scanf("%d",&a[i].x);
        a[i].f=0;
        sum+=a[i].x;
    }
    if(sum>=n)cout<<"NO"<<endl;
    else
    {
        cout<<"YES"<<endl;
        int fl=n-1;//fl记录遍历的位置
        for(int i=n-1;i>=0;i--)//从后向前遍历
        {
            if(a[i].x>0)
            {
                int l;
                for(int j=fl;j>=0;j--)
                {
                    if(a[j].f==0)
                    {
                        l=j;
                        break;
                    }
                }
                fl-=a[i].x;
                for(int k=l;k>l-a[i].x;k--)//被杀的人
                {
                    cout<<i+1<<" "<<k+1<<endl;
                    a[k].f=1;
                }

            }
        }
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值