bzoj4395[Usaco2015 dec]Switching on the Lights*

bzoj4395[Usaco2015 dec]Switching on the Lights

题意:

n*n个房间,奶牛初始在(1,1),且只能在亮的房间里活动。每当奶牛经过一个房间,就可以打开这个房间里控制其它房间灯的开关。问奶牛最多可点亮多少个房间。n≤100。

题解:

因为只要一个房间灯亮了,它将一直亮着,所以可以做bfs,每次由队列中的节点扩展可以到的节点。然而这样做不行,因为可能之前尝试过不能到达的房间的灯可以在之后到达的房间里被打开。解决方法是不停做bfs,直到答案不再更新。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 110
 7 using namespace std;
 8
 9 inline int read(){
10     char ch=getchar(); int f=1,x=0;
11     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
12     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
13     return f*x;
14 }
15 struct nd{int x,y,n;}nds[maxn*200]; int g[maxn][maxn];
16 int n,m,ans; bool lg[maxn][maxn],vis[maxn][maxn]; queue<pair<int,int> >q;
17 void bfs(int x,int y){
18     while(!q.empty())q.pop(); memset(vis,0,sizeof(vis)); q.push(make_pair(x,y)); vis[x][y]=1;
19     for(int i=g[x][y];i;i=nds[i].n)if(!lg[nds[i].x][nds[i].y])lg[nds[i].x][nds[i].y]=1,ans++;
20     while(!q.empty()){
21         int nowx=q.front().first,nowy=q.front().second; q.pop();
22         if(nowx>1&&lg[nowx-1][nowy]&&!vis[nowx-1][nowy]){
23             q.push(make_pair(nowx-1,nowy)); vis[nowx-1][nowy]=1;
24             for(int i=g[nowx-1][nowy];i;i=nds[i].n)
25                 if(!lg[nds[i].x][nds[i].y])lg[nds[i].x][nds[i].y]=1,ans++;
26         }
27         if(nowx<n&&lg[nowx+1][nowy]&&!vis[nowx+1][nowy]){
28             q.push(make_pair(nowx+1,nowy)); vis[nowx+1][nowy]=1;
29             for(int i=g[nowx+1][nowy];i;i=nds[i].n)
30                 if(!lg[nds[i].x][nds[i].y])lg[nds[i].x][nds[i].y]=1,ans++;
31         }
32         if(nowy>1&&lg[nowx][nowy-1]&&!vis[nowx][nowy-1]){
33             q.push(make_pair(nowx,nowy-1)); vis[nowx][nowy-1]=1;
34             for(int i=g[nowx][nowy-1];i;i=nds[i].n)
35                 if(!lg[nds[i].x][nds[i].y])lg[nds[i].x][nds[i].y]=1,ans++;
36         }
37         if(nowy<n&&lg[nowx][nowy+1]&&!vis[nowx][nowy+1]){
38             q.push(make_pair(nowx,nowy+1)); vis[nowx][nowy+1]=1;
39             for(int i=g[nowx][nowy+1];i;i=nds[i].n)
40                 if(!lg[nds[i].x][nds[i].y])lg[nds[i].x][nds[i].y]=1,ans++;
41         }
42     }
43 }
44 int main(){
45     n=read(); m=read();
46     inc(i,1,m){
47         int a=read(),b=read(),c=read(),d=read(); nds[i]=(nd){c,d,g[a][b]}; g[a][b]=i;
48     }
49     ans=1; lg[1][1]=1;
50     while(1){int x=ans; bfs(1,1); if(ans==x)break;} printf("%d",ans); return 0;
51 }

20160908

时间: 2024-10-12 12:35:16

bzoj4395[Usaco2015 dec]Switching on the Lights*的相关文章

4395: [Usaco2015 dec]Switching on the Lights

每次到达一个点,或者点亮一个房间的灯的时候,检查一下它四周的点能否走. 一开始看错题了..要求的是最多能开多少房的灯. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int maxn=10023; 8 const int xx[4]=

bzoj4390: [Usaco2015 dec]Max Flow

4390: [Usaco2015 dec]Max Flow Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 139  Solved: 85[Submit][Status][Discuss] Description Farmer John has installed a new system of N−1 pipes to transport milk between the N stalls in his barn (2≤N≤50,000), co

bzoj4393: [Usaco2015 Dec]Fruit Feast

题意: T,A,B.T是上限.A和B可以随意吃但是不能超过T.有一次将吃的东西/2的机会.然后可以继续吃,不能超过T.问最多可以吃多少. =>我们先处理不能/2可以吃到哪些.然后弄个双指针扫一扫就可以了TAT #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s

bzoj4397【Usaco2015 Dec】Breed Counting

4397: [Usaco2015 dec]Breed Counting Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 29  Solved: 25 [Submit][Status][Discuss] Description Farmer John's N cows, conveniently numbered 1-N, are all standing in a row (they seem to do so often that it now

bzoj4396[Usaco2015 dec]High Card Wins*

bzoj4396[Usaco2015 dec]High Card Wins 题意: 一共有2n张牌,Alice有n张,Bob有n张,每一局点数大的赢.知道Bob的出牌顺序,求Alice最多能赢几局.n≤50000. 题解: 贪心.将Alice和Bob的牌按点数大小排序,然后如果Alice当前牌能赢Bob当前牌就ans++否则就不断调整Bob的当前牌直到Alice当前牌能赢Bob当前牌. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #

bzoj4397[Usaco2015 dec]Breed Counting*

bzoj4397[Usaco2015 dec]Breed Counting 题意: 给定一个长度为N的序列,每个位置上的数只可能是1,2,3中的一种.有Q次询问,每次给定两个数a,b,请分别输出区间[a,b]里数字1,2,3的个数.n≤100000,q≤100000. 题解: 裸前缀和. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for

bzoj4390: [Usaco2015 dec]Max Flow(LCA+树上差分)

题目大意:给出一棵树,n(n<=5w)个节点,k(k<=10w)次修改,每次给定s和t,把s到t的路径上的点权+1,问k次操作后最大点权. 对于每次修改,给s和t的点权+1,给lca(s,t)和lca(s,t)的父亲的点权-1,每一个点的权就是它与它的子树权和,实际上就是树上的差分,又涨姿势了... 代码如下: uses math; type point=^rec; rec=record data:longint; next:point; end; var n,m,x,y,i,ans,fa,k

bzoj4397【Usaco2015 Dec】Breed Counting(前缀和、树状数组)

题目描述 Farmer John's N cows, conveniently numbered 1…N, are all standing in a row (they seem to do so often that it now takes very little prompting from Farmer John to line them up). Each cow has a breed ID: 1 for Holsteins, 2 for Guernseys, and 3 for

[Usaco2015 dec]Max Flow

Description Farmer John has installed a new system of N?1 pipes to transport milk between the N stalls in his barn (2≤N≤50,000), conveniently numbered 1-N. Each pipe connects a pair of stalls, and all stalls are connected to each-other via paths of p