【深搜】【数】Codeforces 707D Persistent Bookcase

题目链接:

  http://codeforces.com/problemset/problem/707/D

题目大意:

  一个N*M的书架,支持4种操作

  1.把(x,y)变为有书。

  2.把(x,y)变为没书。

  3.把x行上的所有书状态改变,有变没,没变有。

  4.回到第K个操作时的状态。

  求每一次操作后书架上总共多少书。

题目思路:

  【深搜】【树】

  现场有一点思路不过没敢写哈。还是太弱了。

  总共只用保存一张图,把操作看成一棵树,一开始I操作连接在I-1操作后,如果遇到操作4的话,把I操作与I-1操作的边断开,改为连接到K下。

  这样把所有操作链完以后得到一棵多叉树,接下来深搜一遍,记录答案,回溯的时候把状态改回去即可。

  1 //
  2 //by coolxxx
  3 //#include<bits/stdc++.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<map>
  9 #include<memory.h>
 10 #include<time.h>
 11 #include<stdio.h>
 12 #include<stdlib.h>
 13 #include<string.h>
 14 //#include<stdbool.h>
 15 #include<math.h>
 16 #define min(a,b) ((a)<(b)?(a):(b))
 17 #define max(a,b) ((a)>(b)?(a):(b))
 18 #define abs(a) ((a)>0?(a):(-(a)))
 19 #define lowbit(a) (a&(-a))
 20 #define sqr(a) ((a)*(a))
 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 22 #define mem(a,b) memset(a,b,sizeof(a))
 23 #define eps (1e-8)
 24 #define J 10
 25 #define mod 1000000007
 26 #define MAX 0x7f7f7f7f
 27 #define PI 3.14159265358979323
 28 #define N 1004
 29 #define M 100005
 30 using namespace std;
 31 typedef long long LL;
 32 int cas,cass;
 33 int n,m,lll,ans;
 34 struct xxx
 35 {
 36     int next,to,q,x,y;;
 37 }a[M];
 38 int last[M],an[M];
 39 bool mapp[N][N];
 40 void add(int x,int y)
 41 {
 42     a[++lll].next=last[x];
 43     a[lll].to=y;
 44     last[x]=lll;
 45 }
 46 void dfs(int now,int sum)
 47 {
 48     int i,j;
 49     an[now]=sum;
 50     for(i=last[now];i;i=a[i].next)
 51     {
 52         if(a[i].q==1)
 53         {
 54             if(mapp[a[i].x][a[i].y])
 55                 dfs(a[i].to,sum);
 56             else
 57             {
 58                 mapp[a[i].x][a[i].y]=1;
 59                 dfs(a[i].to,sum+1);
 60                 mapp[a[i].x][a[i].y]=0;
 61             }
 62         }
 63         else if(a[i].q==2)
 64         {
 65             if(mapp[a[i].x][a[i].y])
 66             {
 67                 mapp[a[i].x][a[i].y]=0;
 68                 dfs(a[i].to,sum-1);
 69                 mapp[a[i].x][a[i].y]=1;
 70             }
 71             else dfs(a[i].to,sum);
 72         }
 73         else if(a[i].q==3)
 74         {
 75             int k=0;
 76             for(j=1;j<=m;j++)
 77             {
 78                 if(mapp[a[i].x][j])k--;
 79                 else k++;
 80                 mapp[a[i].x][j]^=1;
 81             }
 82             dfs(a[i].to,sum+k);
 83             for(j=1;j<=m;j++)mapp[a[i].x][j]^=1;
 84         }
 85         else if(a[i].q==4)
 86             dfs(a[i].to,sum);
 87     }
 88 }
 89 int main()
 90 {
 91     #ifndef ONLINE_JUDGE
 92 //    freopen("1.txt","r",stdin);
 93 //    freopen("2.txt","w",stdout);
 94     #endif
 95     int i,j,k;
 96     int x,y;
 97 //    for(scanf("%d",&cas);cas;cas--)
 98 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 99 //    while(~scanf("%s",s+1))
100     while(~scanf("%d",&n))
101     {
102         //lll=0;mem(fa,0);mem(last,0);
103         scanf("%d%d",&m,&cas);
104         for(i=1;i<=cas;i++)
105         {
106             scanf("%d",&a[i].q);
107             if(a[i].q<3)
108                 scanf("%d%d",&a[i].x,&a[i].y);
109             else if(a[i].q==3)
110                 scanf("%d",&a[i].x);
111             else if(a[i].q==4)
112             {
113                 scanf("%d",&a[i].x);
114                 add(a[i].x,i);
115                 continue;
116             }
117             add(i-1,i);
118         }
119         dfs(0,0);
120         for(i=1;i<=cas;i++)
121             printf("%d\n",an[i]);
122         puts("");
123     }
124     return 0;
125 }
126 /*
127 //
128
129 //
130 */

时间: 2024-10-25 09:47:39

【深搜】【数】Codeforces 707D Persistent Bookcase的相关文章

CodeForces 707D Persistent Bookcase

$dfs$,优化. $return$操作说明该操作完成之后的状态和经过操作$k$之后的状态是一样的.因此我们可以建树,然后从根节点开始$dfs$一次(回溯的时候复原一下状态)就可以算出所有状态的答案. 对于$1$和$2$操作,可以开一个数组$a[i][j]$记录每一格子被操作$1$和$2$操作了几次. 然后开一个数组$r[i]$记录每一行被操作$3$操作了几次. 每一个真正的状态为$\left( {a\left[ i \right]\left[ j \right] + r\left[ i \ri

CodeForces 707D Persistent Bookcase ——(巧妙的dfs)

一个n*m的矩阵,有四种操作: 1.(i,j)处变1: 2.(i,j)处变0: 3.第i行的所有位置1,0反转: 4.回到第k次操作以后的状态: 问每次操作以后整个矩阵里面有多少个1. 其实不好处理的操作只有第四个,但是这题的思路很巧妙,123三种操作全部建立顺边,第四种操作将k和这次操作的序号建边,然后dfs进行操作即可,遇到尽头,则退回到前一个分岔点,并且回溯的过程中将操作反转. 具体见代码: 1 #include <stdio.h> 2 #include <algorithm>

方格取数(多线程dp,深搜)

https://www.luogu.org/problem/P1004 题目描述 设有N×N的方格图(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样例): 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B点.在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0).此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和为最大. 输入格式 输入的第一行为一个整数N(表示N×N的方格图),接下来的每行有三个整数,前

深搜--P1036选数

深搜中绝对会用到递归 因此本题也可以使用深搜来做 bool prime(int b) { memset(sz, true, sizeof(sz)); sz[1]=false; for (int i=2;i<=b;i++) { if (sz[i]) { for (int j=2*i;j<=b;j+=i) sz[j]=false; 定义一个dfs函数来解决对数的搜索 step代表执行步数 sum代表已经选好的数据的和 cet代表已经选完的数的个数 接下来进行搜索 另外介绍下非朴素版的寻找质数的方法

Codeforces Round #222 (Div. 1)A. Maze(深搜)

传送门 Description Pavel loves grid mazes. A grid maze is an n × m rectangle maze where each cell is either empty, or is a wall. You can go from one cell to another only if both cells are empty and have a common side. Pavel drew a grid maze with all emp

CodeForces #368 div2 D Persistent Bookcase DFS

题目链接:D Persistent Bookcase 题意:有一个n*m的书架,开始是空的,现在有k种操作: 1 x y 这个位置如果没书,放书. 2 x y 这个位置如果有书,拿走. 3 x 反转这一行,即有书的位置拿走,没书的位置放上书. 4 x 返回到第x步操作之后的书架. 现在给出q个操作,询问每次操作之后书架上书的数量. 思路: 开始没有思路.后来被告知dfs. [词不达意.参考:http://blog.csdn.net/zyjhtutu/article/details/5227949

hdu1455 Sticks 深搜 强剪枝

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6035    Accepted Submission(s): 1704 Problem Description George took sticks of the same length and cut them randomly until all parts becam

HDU5723 Abandoned country 最小生成树+深搜回溯法

Description An abandoned country has n(n≤100000) villages which are numbered from 1 to n. Since abandoned for a long time, the roads need to be re-built. There are m(m≤1000000) roads to be re-built, the length of each road is wi(wi≤1000000). Guarante

深搜———ZOJ 1004:anagrams by stack

细节问题各种虐!! 其实就是简单的一个深搜 看成二叉树来理解:每个节点有两个枝:入栈和出栈. 剪枝操作:只有当栈顶元素和当前位置的目标字符相同时才出栈,否则就不出栈 dfs写三个参数:depth搜索深度,npush压栈数,npop出栈数 npush用于记录压栈数:主要判断当前压栈是否合理,以及要压入的元素在原串种的位置 npop用于记录出栈数:判断生成的目标串元素的位置 当npush==npop==目标串时,说明生成了一个可执行的操作串 注意输出操作串的时候一定要用depth参数来控制,因为在多