Chef and Strange Matrix 思维题好题

Read problems statements in Mandarin Chinese and Russian.

Spring is interesting season of year. Chef is thinking about different things, but last time he thinks about interesting game - "Strange Matrix".

Chef has a matrix that consists of n rows, each contains m elements. Initially, the element aij of matrix equals j(1 ≤ i ≤ n, 1 ≤ j ≤ m).

Then p times some element aij is increased by 1.

Then Chef needs to calculate the following:

  • For each row he tries to move from the last element (with number m) to the first one (with the number 1).
  • While staying in aij Chef can only move to aij - 1 only if aij - 1 ≤ aij.
  • The cost of such a movement is aij - aij - 1.
  • Otherwise Chef can't move and lose (in this row).
  • If Chef can move from the last element of the row to the first one, then the answer is the total cost of all the movements.
  • If Chef can't move from the last element of the row to the first one, then the answer is -1.

 

Help Chef to find answers for all the rows after P commands of increasing.

Input

 

  • The first line contains three integers nm and p denoting the number of rows, the number of elements a single row and the number of increasing commands.
  • Each of next p lines contains two integers i and j denoting that the element aijis increased by one.

 

Output

  • For each row in a single line print the answer after the P increasing commands.

 

Constraints

  • 1 ≤ n, m, p ≤ 10 ^ 5
  • 1 ≤ i ≤ n
  • 1 ≤ j ≤ m

 

Example

Input:
4 4 6
2 2
3 2 
3 2 
4 3
4 4
4 3

Output:
3
3
-1
4

Explanation

Here is the whole matrix after P commands:

1 2 3 4 1 3 3 4 1 4 3 4 1 2 5 5

Explanations to the answer:

  • The first line is without changes: 4-3=1, 3-2=1, 2-1=1. answer = 3.
  • The second line: 4-3=1, 3-3=0, 3-1=2. The answer is 3.
  • The third line: 4-3=1, 3-4=-1, Chef can't move to the first number here. Therefore, the answer is -1.
  • The fourth line: 5-5=0, 5-2=3, 2-1=1. The answer is 4.

    题意很容易懂 就是给你给二维的矩阵(N x M 每一行的初始化都是 (1--m)  然后输入P 次 i j 代表 第 i 行 j 列的数值加 1 然后问你每一行从最后一个位置m能不能到达第一个位置 再走的过程中 对于某一行x 第 j列 能到达第j-1列的条件是 a[x][j]>=a[x][j-1] 代价是 a[x][j]-a[x][j-1] 如果能够到达会输出代价 不能够到达就输出-1


    思路:看代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    struct Node
    {
        int x,y;
    }s[maxn];
    bool cmp(Node a,Node b)
    {
        if(a.x==b.x)
            return a.y<b.y;
        return a.x<b.x;
    }
    int ans[maxn];
    int sum[maxn];
    int num[maxn];
    int main()
    {
           int n,m,p;
           scanf("%d%d%d",&n,&m,&p);
           for(int i=1;i<=n;i++)//初始化
            ans[i]=m-1;
           for(int i=1;i<=p;i++)
               scanf("%d%d",&s[i].x,&s[i].y);
           sort(s+1,s+1+p,cmp);//对第一元素小到大然后第二元素小到大
           for(int i=1;i<=p;i++)
               sum[s[i].x]++;//记录每一行出现的个数
          for(int i=1;i<=p;i++)
          {
              for(int j=i;j<i+sum[s[i].x];j++)//争对每一行记录每一列出现的个数
                  num[s[j].y]++;
              int flag=0;
              for(int j=i;j<i+sum[s[i].x];j++)
              {
                  if(num[s[j].y]>num[s[j].y+1]+1&&s[j].y+1<=m)//判断中间是否成立
                  {
                      flag=1;
    
                      break;
                  }
                   if(num[s[j].y-1]>num[s[j].y]+1&&s[j].y-1>=1)/判断中间是否成立
                  {
                      flag=1;
                      break;
                  }
              }
              if(flag)
                ans[s[i].x]=-1;
              else
              {
                  ans[s[i].x]=num[m]+m-num[1]-1;//对于你改变中间的元素的值(除1和m) 不会影响整个答案
              }
              for(int j=i;j<i+sum[s[i].x];j++)//把记录的值清0 
                num[s[j].y]--;
              i=i+sum[s[i].x]-1;//跳转下一行
          }
          for(int i=1;i<=n;i++)
            printf("%d\n",ans[i]);
    
        return 0;
    }
    

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值