CF Round 344 --B. Print Check

Kris works in a large company "Blake Technologies". As a best engineer of the company he was assigned a task to develop a printer that will be able to print horizontal and vertical strips. First prototype is already built and Kris wants to tests it. He wants you to implement the program that checks the result of the printing.

Printer works with a rectangular sheet of paper of size n × m. Consider the list as a table consisting of n rows and m columns. Rows are numbered from top to bottom with integers from 1 to n, while columns are numbered from left to right with integers from 1 to m. Initially, all cells are painted in color 0.

Your program has to support two operations:

  1. Paint all cells in row ri in color ai;
  2. Paint all cells in column ci in color ai.

If during some operation i there is a cell that have already been painted, the color of this cell also changes to ai.

Your program has to print the resulting table after k operation.

Input

The first line of the input contains three integers nm and k (1  ≤  n,  m  ≤ 5000, n·m ≤ 100 000, 1 ≤ k ≤ 100 000) — the dimensions of the sheet and the number of operations, respectively.

Each of the next k lines contains the description of exactly one query:

  • ri ai (1 ≤ ri ≤ n, 1 ≤ ai ≤ 109), means that row ri is painted in color ai;
  • ci ai (1 ≤ ci ≤ m, 1 ≤ ai ≤ 109), means that column ci is painted in color ai.

Output

Print n lines containing m integers each — the resulting table after all operations are applied.

题意:n*m的矩阵初始都是0,有k次操作(op,x,y),如果op=1,那么把第x行全部设置为y,如果op=2,那么将第x列设置为y,问最后的矩阵。

解析:因为某一行某一列多次操作,那么最终结果肯定取决于最后一次,因为会不断覆盖,因此我们可以离线读入每次操作,倒着遍历,只取第一次遍历到该行和该列的操作,存入一个结构体,最后遍历赋值即可。

#include 
using namespace std;
const int N=1e5+5,M=5005;
int op[N],x[N],y[N];//记录操作
int a[M][M];//保存矩阵
bool mp[M][M];//判断{op,x}是否出现过
struct s
{
    int op,x,y;
}tr[N];
void solve()
{
    int n,m,k,cnt=0;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++) scanf("%d%d%d",&op[i],&x[i],&y[i]);
    for(int i=k;i>=1;i--)//倒着遍历
    {
        if(!mp[op[i]][x[i]])//第一次遇到
        {
            tr[++cnt]={op[i],x[i],y[i]};//将操作存下
            mp[op[i]][x[i]]=true;
        }
    }
    for(int i=cnt;i>=1;i--)
    {
        int op=tr[i].op;
        int x=tr[i].x;
        int y=tr[i].y;
        if(op==1) for(int i=1;i<=m;i++) a[x][i]=y;//遍历赋值
        else for(int i=1;i<=n;i++) a[i][x]=y;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++) printf("%d ",a[i][j]);
        printf("\n");
    }
}
int main()
{
    int t=1;
    //scanf("%d",&t);
    while(t--) solve();
    return 0;
}

你可能感兴趣的:(c++,c语言)