【搜索树】【dfs】【模拟】I Like Matrix Forever!

题目:

对一个 n ∗ m 的零矩阵 A 进行 q 次操作:
• 1 i j:将 Ai,j 取反;
• 2 i:将矩阵 A 第 i 行的所有元素全部取反;
• 3 j:将矩阵 A 第 j 列的所有元素全部取反;
• 4 k:将矩阵 A 还原为第 k 次操作之后的状态。
进行每一次操作之后,询问当前矩阵所有元素的和。


输入:

第一行包含三个整数 n,m 和 q。
之后 q 行每行包含两个或三个整数,表示一次操作的所有参数。


输出:

共 q 行每行包含一个整数 ans,表示当前矩阵所有元素的和。


样例输入:

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

样例输出:

2
1
2
1

思路:

这题我们可以用搜索树做,把操作想象为一个个子节点,然后模拟三种操作,去翻就+1%2,还要加快读和快输,最后就是代码量比较长,仔细打就好了。


代码:

#include
#include
using namespace std;
int sum,a[10000][10000],x[100000],y[100000],ans[100000],l[100000],h[100000],n,m,q,t;
struct node//建邻接表用
{
	int  w,p;
}e[100000001];
void add(int x,int y){e[++t]=(node){y,h[x]}; h[x]=t;}//领接表
int read()//快读
{
	int x=0,flag=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*flag;
}
void write(int x)//快输
{
    if(x<0) {x=-x;putchar('-');}
	if(x>9) write(x/10);
	putchar(x%10+48);
	return;
}
void dfs(int dep)//dfs
{
	if(l[dep]==1)//模拟
	{
		sum+=1-(a[x[dep]][y[dep]]*2);//(*2=<<1)
		a[x[dep]][y[dep]]=(a[x[dep]][y[dep]]+1)%2;//取反
	}
	else if(l[dep]==2)//模拟
	{
		for(int i=1;i<=m;i++)//行
		{
			sum+=1-(a[x[dep]][i]*2);
		    a[x[dep]][i]=(a[x[dep]][i]+1)%2;
		}
	}
	else if(l[dep]==3)	
	{
		for(int i=1;i<=n;i++)//列
		{
			sum+=1-(a[i][x[dep]]*2);
			a[i][x[dep]]=(a[i][x[dep]]+1)%2;
		}
	}
	 ans[dep]+=sum;//累加当前矩阵的元素和
	for(int i=h[dep];i;i=e[i].p)	dfs(e[i].w);//搜索
	    if(l[dep]==1)//重复之前的步骤
	    {
		sum+=1-(a[x[dep]][y[dep]]*2);
		a[x[dep]][y[dep]]=(a[x[dep]][y[dep]]+1)%2;
     	}
	    else if(l[dep]==2)
	{
		for(int i=1;i<=m;i++)
		{
			sum+=1-(a[x[dep]][i]*2);
		    a[x[dep]][i]=(a[x[dep]][i]+1)%2;
		}
	}
	   else if(l[dep]==3)
	{
		for(int i=1;i<=n;i++)
		{
			sum+=1-(a[i][x[dep]]*2);
			a[i][x[dep]]=(a[i][x[dep]]+1)%2;
		}
	}
	return;
}
int main()
{
	n=read();m=read();q=read();//输入
	for(int i=1;i<=q;i++)
	{
		l[i]=read();x[i]=read();
		if(l[i]==1)y[i]=read();
		if (l[i]!=4) add(i-1,i);//连边(前一个操作)
	  	else add(x[i],i);//连接回到的点
	}
	dfs(0);//从版本0开始搜
	for(int i=1;i<=q;i++)//输出的行数
    {write(ans[i]);printf("\n");}//输出+换行
	return 0;
} 

你可能感兴趣的:(深搜,搜索树,模拟)