有一种恐怖,叫大爆搜
到目前这个阶段,大爆搜做了好几个,有必要做一下小的总结了。
玛雅游戏:出门左转 http://www.cnblogs.com/Loser-of-Life/p/7247413.html的A
斗地主:出门右转http://www.cnblogs.com/Loser-of-Life/p/7259858.html的B
天鹅会面:出门直行http://www.cnblogs.com/Loser-of-Life/p/7295770.html的A
引水入城:链接:http://cogs.pro/cogs/problem/problem.php?pid=521
先正向$bfs$判断一下是否存在解,然后反向$bfs$,运用贪心策略选择最长线段进行覆盖。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int maxn=505; 8 int a[maxn][maxn],mp[maxn][maxn],l[maxn][maxn],r[maxn][maxn],n,m; 9 int px[4]={1,-1,0,0},py[4]={0,0,1,-1}; 10 typedef pair<int,int> pii; 11 void bfs(int b[maxn][maxn],int x,int y,int v,int f) 12 { 13 queue<pii>q;q.push(make_pair(x,y));b[x][y]=v; 14 while(!q.empty()) 15 { 16 pii p=q.front();q.pop(); 17 x=p.first,y=p.second; 18 for(int i=0;i<4;i++) 19 { 20 int nowx=x+px[i],nowy=y+py[i]; 21 if(nowx<1||nowx>n||nowy<1||nowy>m||b[nowx][nowy])continue; 22 if(!f&&a[nowx][nowy]>=a[x][y])continue; 23 if(f&&a[nowx][nowy]<=a[x][y])continue; 24 b[nowx][nowy]=b[x][y]; 25 q.push(make_pair(nowx,nowy)); 26 } 27 } 28 } 29 struct data 30 { 31 int l,r; 32 }c[maxn]; 33 inline bool cmp(data a,data b) 34 { 35 if(a.l!=b.l)return a.l<b.l; 36 return a.r<b.r; 37 } 38 int haha() 39 { 40 freopen("flow.in","r",stdin); 41 freopen("flow.out","w",stdout); 42 scanf("%d%d",&n,&m); 43 for(int i=1;i<=n;i++) 44 for(int j=1;j<=m;j++)scanf("%d",&a[i][j]); 45 for(int i=1;i<=m;i++)bfs(mp,1,i,1,0); 46 int tot=0; 47 for(int i=1;i<=m;i++) 48 if(!mp[n][i])tot++; 49 if(tot) 50 { 51 printf("0\n%d\n",tot); 52 return 0; 53 } 54 for(int i=1;i<=m;i++) 55 if(!l[n][i])bfs(l,n,i,i,1); 56 for(int i=m;i;i--) 57 if(!r[n][i])bfs(r,n,i,i,1); 58 for(int i=1;i<=m;i++) 59 { 60 if(!l[1][i])l[1][i]=r[1][i]; 61 if(!r[1][i])r[1][i]=l[1][i]; 62 c[i].l=l[1][i],c[i].r=r[1][i]; 63 } 64 sort(c+1,c+m+1,cmp); 65 int now=0,to=0; 66 for(int i=1;i<=m;i++) 67 if(now+1>=c[i].l)to=max(to,c[i].r); 68 else 69 { 70 now=to; 71 to=max(to,c[i].r); 72 tot++; 73 } 74 if(now!=m)tot++; 75 printf("1\n%d\n",tot); 76 } 77 int sb=haha(); 78 int main(){;}
靶形数独:链接:http://cogs.pro/cogs/problem/problem.php?pid=407
说好的状压启发式搜索呢?怎么是裸的$dfs$?虽然我很喜欢……港真,我今天下午颓了半下午这道题样例……和$wcx$比赛数独结果对面最后还剩两步发现他全错……欢声笑语中打出$GG$……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct node 7 { 8 int x,y; 9 }V[101]; 10 int v[9][9]={ 11 {1,1,1,2,2,2,3,3,3}, 12 {1,1,1,2,2,2,3,3,3}, 13 {1,1,1,2,2,2,3,3,3}, 14 {4,4,4,5,5,5,6,6,6}, 15 {4,4,4,5,5,5,6,6,6}, 16 {4,4,4,5,5,5,6,6,6}, 17 {7,7,7,8,8,8,9,9,9}, 18 {7,7,7,8,8,8,9,9,9}, 19 {7,7,7,8,8,8,9,9,9} 20 },x,ans=-1,tim=0; 21 int w[9][9]={ 22 {6,6,6,6,6,6,6,6,6}, 23 {6,7,7,7,7,7,7,7,6}, 24 {6,7,8,8,8,8,8,7,6}, 25 {6,7,8,9,9,9,8,7,6}, 26 {6,7,8,9,10,9,8,7,6}, 27 {6,7,8,9,9,9,8,7,6}, 28 {6,7,8,8,8,8,8,7,6}, 29 {6,7,7,7,7,7,7,7,6}, 30 {6,6,6,6,6,6,6,6,6} 31 },tot=0; 32 int vis[10][10],lx[10][10],ly[10][10]; 33 void dfs(int rem,int now) 34 { 35 if(!rem) 36 { 37 ans=max(ans,now); 38 return; 39 } 40 for(int i=1;i<=9;i++) 41 if(!vis[v[V[rem].x][V[rem].y]][i]&&!lx[V[rem].x][i]&&!ly[V[rem].y][i]) 42 { 43 vis[v[V[rem].x][V[rem].y]][i]=1; 44 lx[V[rem].x][i]=1; 45 ly[V[rem].y][i]=1; 46 dfs(rem-1,now+w[V[rem].x][V[rem].y]*i); 47 vis[v[V[rem].x][V[rem].y]][i]=0; 48 lx[V[rem].x][i]=0; 49 ly[V[rem].y][i]=0; 50 } 51 } 52 int haha() 53 { 54 freopen("sudoku.in","r",stdin); 55 freopen("sudoku.out","w",stdout); 56 int stat=0; 57 for(int i=0;i<9;i++) 58 for(int j=0;j<9;j++) 59 { 60 int x;scanf("%d",&x); 61 if(!x)V[++tot]=(node){i,j}; 62 else 63 { 64 stat+=x*w[i][j]; 65 vis[v[i][j]][x]=lx[i][x]=ly[j][x]=1; 66 } 67 } 68 dfs(tot,stat); 69 printf("%d\n",ans); 70 } 71 int sb=haha(); 72 int main(){;}
传染病控制:链接:http://cogs.pro/cogs/problem/problem.php?pid=107
果然$CCF$老爷机啊……正常情况下每一次都是要剪枝的,但是在评测机上直接裸$dfs$,每一层暴力判断,改都不改就过了……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=310; 7 struct node 8 { 9 int from,to,next; 10 }edge[maxn<<1]; 11 int head[maxn],tot; 12 void addedge(int u,int v) 13 { 14 edge[++tot]=(node){u,v,head[u]};head[u]=tot; 15 } 16 int fa[maxn],n,m,deep[maxn][maxn]; 17 bool cutt[maxn]; 18 void cut(int root) 19 { 20 cutt[root]=1; 21 for(int i=head[root];i;i=edge[i].next) 22 { 23 int v=edge[i].to; 24 if(v!=fa[root])cut(v); 25 } 26 } 27 void rebuild(int root) 28 { 29 cutt[root]=0; 30 for(int i=head[root];i;i=edge[i].next) 31 { 32 int v=edge[i].to; 33 if(v!=fa[root])rebuild(v); 34 } 35 } 36 int siz[maxn]; 37 void dfs(int root,int dep) 38 { 39 siz[root]=1;deep[dep][++deep[dep][0]]=root; 40 for(int i=head[root];i;i=edge[i].next) 41 { 42 int v=edge[i].to; 43 if(v!=fa[root]) 44 { 45 fa[v]=root; 46 dfs(v,dep+1); 47 siz[root]+=siz[v]; 48 } 49 } 50 } 51 int maxl=-1; 52 void dfss(int dep,int num) 53 { 54 maxl=max(maxl,num); 55 for(int i=1;i<=deep[dep][0];i++) 56 if(!cutt[deep[dep][i]]) 57 { 58 cut(deep[dep][i]); 59 dfss(dep+1,num+siz[deep[dep][i]]); 60 rebuild(deep[dep][i]); 61 } 62 } 63 int haha() 64 { 65 freopen("epidemic.in","r",stdin); 66 freopen("epidemic.out","w",stdout); 67 scanf("%d%d",&n,&m); 68 for(int i=1;i<=m;i++) 69 { 70 int u,v;scanf("%d%d",&u,&v); 71 addedge(u,v);addedge(v,u); 72 } 73 dfs(1,1); 74 dfss(2,0); 75 printf("%d\n",n-maxl); 76 //for(int i=1;i<=n;i++)cout<<siz[i]<<" "; 77 //puts(""); 78 } 79 int sb=haha(); 80 int main(){;}
字串变换:链接:http://cogs.pro/cogs/problem/problem.php?pid=65
这果然是那个没有$STL$的时代啊……原来可是要$Hash$加$Treap$判重的,现在$std::queue$、$std::queue$、$std::map$、$std::string$直接碾压……除去这些,就是一个双向广搜。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<map> 6 #include<string> 7 #include<queue> 8 using namespace std; 9 struct node 10 { 11 string s;int num; 12 }; 13 queue<node>q1,q2; 14 map<string,int>m1,m2; 15 string changings[6][2]; 16 int cnt,ans; 17 string become(string now,int pos,int n,string tmp) 18 { 19 return now.replace(pos,n,tmp); 20 } 21 bool dbfs() 22 { 23 while(!q1.empty()&&!q2.empty()) 24 { 25 node s1=q1.front(),s2;q1.pop(); 26 int len=s1.s.size(); 27 for(int i=0;i<len;i++) 28 for(int j=0;j<cnt;j++) 29 { 30 int siz=changings[j][0].size(); 31 if(i+siz-1<len&&!s1.s.compare(i,siz,changings[j][0])&&!m1.count(become(s1.s,i,siz,changings[j][1]))) 32 { 33 s2.s=become(s1.s,i,siz,changings[j][1]); 34 s2.num=s1.num+1; 35 if(s2.num>10)return 0; 36 m1[s2.s]=s2.num;q1.push(s2); 37 if(m2.count(s2.s)) 38 { 39 ans=s2.num+m2[s2.s]; 40 return 1; 41 } 42 } 43 } 44 s1=q2.front(),s2;q2.pop(); 45 len=s1.s.size(); 46 for(int i=0;i<len;i++) 47 for(int j=0;j<cnt;j++) 48 { 49 int siz=changings[j][1].size(); 50 if(i+siz-1<len&&!s1.s.compare(i,siz,changings[j][1])&&!m2.count(become(s1.s,i,siz,changings[j][0]))) 51 { 52 s2.s=become(s1.s,i,siz,changings[j][0]); 53 s2.num=s1.num+1; 54 if(s2.num>10)return 0; 55 m2[s2.s]=s2.num;q2.push(s2); 56 if(m1.count(s2.s)) 57 { 58 ans=s2.num+m1[s2.s]; 59 return 1; 60 } 61 } 62 } 63 } 64 return 0; 65 } 66 int haha() 67 { 68 freopen("string.in","r",stdin); 69 freopen("string.out","w",stdout); 70 node a,b;cin>>a.s>>b.s; 71 if(a.s==b.s) 72 { 73 cout<<0; 74 return 0; 75 } 76 a.num=b.num=0; 77 q1.push(a);q2.push(b); 78 while(cin>>changings[cnt][0]>>changings[cnt][1])cnt++; 79 m1[a.s]=0;m2[b.s]=0; 80 if(dbfs())cout<<ans; 81 else puts("NO ANSWER!"); 82 } 83 int sb=haha(); 84 int main(){;}
我回来一定要总结$std::string$来骗一波访问量(有生之年系列)
栅栏:链接:http://cogs.pro/cogs/problem/problem.php?pid=882
神之思路……首先显然可以证明这个选择木板的数量是具有单调性的……于是我们二分答案……二分之后问题就变成是否存在一种方式使这个数量木板被锯出来……然后里面有一些神之剪枝……感性理解一下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int M=60,N=1050; 6 int all,n,m,num,give[M],need[N],sum[N]; 7 bool dfs(int id,int pre,int rabbage) 8 { 9 int i;bool ok; 10 if(!id)return 1; 11 if(sum[num]+rabbage>all)return 0; 12 for(i=(need[id]==need[id+1])?pre:1;i<=m;++i) 13 if(give[i]>=need[id]) 14 { 15 give[i]-=need[id]; 16 ok=dfs(id-1,i,rabbage+(give[i]<need[1])?give[i]:0); 17 give[i]+=need[id]; 18 if(ok)return 1; 19 } 20 return 0; 21 } 22 int main() 23 { 24 freopen("fence8.in","r",stdin); 25 freopen("fence8.out","w",stdout); 26 // freopen("Lex.in","r",stdin); 27 register int i; 28 scanf("%d",&m); 29 for(i=1;i<=m;++i) 30 scanf("%d",&give[i]),all+=give[i]; 31 scanf("%d",&n); 32 for(i=1;i<=n;++i) 33 scanf("%d",&need[i]); 34 sort(need+1,need+n+1); 35 for(i=1;i<=n;++i)sum[i]=sum[i-1]+need[i]; 36 int l=0,r=n,ans=0; 37 while(l<=r) 38 { 39 num=(l+r)>>1; 40 if(dfs(num,1,0))l=num+1,ans=num; 41 else r=num-1; 42 } 43 printf("%d\n",ans); 44 }
寻找道路:链接:http://cogs.pro/cogs/problem/problem.php?pid=1807
首先构建出反图,$dfs$找到每一个可以直接或者间接连接到终点的点,然后正向$dfs$搞出来每一个点是否所有出边都可以连接终点……之后就用这些点里面的边跑最短路……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=10005,maxm=200005; 7 struct node 8 { 9 int from,to,next; 10 }edge[maxm],edge2[maxm]; 11 int head[maxn],tot,head2[maxn],tot2; 12 void addedge(int u,int v) 13 { 14 edge[++tot]=(node){u,v,head[u]};head[u]=tot; 15 edge2[++tot2]=(node){v,u,head2[v]};head2[v]=tot2; 16 } 17 int n,m,S,T; 18 bool canreach[maxn]; 19 void dfs(int now) 20 { 21 canreach[now]=1; 22 for(int i=head2[now];i;i=edge2[i].next) 23 { 24 int v=edge2[i].to; 25 if(!canreach[v])dfs(v); 26 } 27 } 28 bool vis[maxn],canpass[maxn]; 29 void dfs2(int now) 30 { 31 canpass[now]=vis[now]=1; 32 if(!canreach[now])canpass[now]=0; 33 for(int i=head[now];i;i=edge[i].next) 34 { 35 int v=edge[i].to; 36 if(!vis[v])dfs2(v); 37 if(!canreach[v])canpass[now]=0; 38 } 39 } 40 #include<queue> 41 queue<int>q; 42 bool inqueue[maxn];int dis[maxn]; 43 void spfa() 44 { 45 memset(dis,0x3f,sizeof(dis));dis[S]=0;inqueue[S]=1;q.push(S); 46 while(!q.empty()) 47 { 48 int now=q.front();q.pop();inqueue[now]=1; 49 for(int i=head[now];i;i=edge[i].next) 50 { 51 int v=edge[i].to; 52 if(canpass[v]&&dis[v]>dis[now]+1) 53 { 54 dis[v]=dis[now]+1; 55 if(!inqueue[v])q.push(v),inqueue[v]=1; 56 } 57 } 58 } 59 if(dis[T]==0x3f3f3f3f)puts("-1"); 60 else printf("%d\n",dis[T]); 61 } 62 int haha() 63 { 64 freopen("roadb.in","r",stdin); 65 freopen("roadb.out","w",stdout); 66 scanf("%d%d",&n,&m); 67 for(int i=1;i<=m;i++) 68 { 69 int x,y;scanf("%d%d",&x,&y); 70 addedge(x,y); 71 } 72 scanf("%d%d",&S,&T);dfs(T);dfs2(S);spfa(); 73 } 74 int sb=haha(); 75 int main(){;}
文化之旅:链接:http://cogs.pro/cogs/problem/problem.php?pid=1271
看上去是个搜索……然而$Floyd$过了……数据太水……= =
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn=105; 7 int c[maxn],a[maxn][maxn],n,k,m,s,t,map[maxn][maxn]; 8 int haha() 9 { 10 freopen("culture.in","r",stdin); 11 freopen("culture.out","w",stdout); 12 scanf("%d%d%d%d%d",&n,&k,&m,&s,&t); 13 for(int i=1;i<=n;i++)scanf("%d",&c[i]); 14 for(int i=1;i<=k;i++) 15 for(int j=1;j<=k;j++)scanf("%d",&a[i][j]); 16 memset(map,0x3f,sizeof(map)); 17 for(int i=1;i<=n;i++)map[i][i]=0; 18 for(int i=1;i<=m;i++) 19 { 20 int x,y,z;scanf("%d%d%d",&x,&y,&z); 21 map[x][y]=map[y][x]=min(z,map[x][y]); 22 } 23 if(c[s]==c[t]||a[t][s]){puts("-1");return 0;} 24 for(int k=1;k<=n;k++) 25 for(int i=1;i<=n;i++) 26 for(int j=1;j<=n;j++) 27 if(k!=i&&k!=j&&i!=j) 28 if(!a[c[i]][c[j]]&&!a[c[i]][c[k]]&&!a[c[j]][c[k]])map[i][j]=min(map[i][j],map[i][k]+map[k][j]); 29 if(map[s][t]==0x3f3f3f3f)puts("-1"); 30 else printf("%d\n",map[s][t]); 31 } 32 int sb=haha(); 33 int main(){;}
虫食算:链接:http://cogs.pro/cogs/problem/problem.php?pid=69
大型分类讨论……我比较蠢写了$8$种情况……再加上并没有随时定义变量减少码量……结果就导致$250$行代码长度$7.8K$……= =码长基本没有超过我的了……写的奇蠢无比凑合看吧……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=27; 7 char s[4][maxn];int f[maxn],n;bool used[maxn]; 8 void dfs(int now,int jinwei) 9 { 10 bool judge=1; 11 if(now==n+1) 12 { 13 for(int i=0;i<n;i++)printf("%d ",f[i]); 14 exit(0); 15 } 16 if(now==n)judge=0; 17 if(f[s[1][now]-'A']==-1&&f[s[2][now]-'A']==-1&&f[s[3][now]-'A']==-1) 18 { 19 for(int i=0;i<n;i++) 20 if(!used[i]) 21 { 22 used[i]=1,f[s[1][now]-'A']=i; 23 dfs(now,jinwei); 24 used[i]=0,f[s[1][now]-'A']=-1; 25 } 26 return ; 27 } 28 if(f[s[1][now]-'A']!=-1&&f[s[2][now]-'A']!=-1&&f[s[3][now]-'A']!=-1) 29 { 30 if(jinwei) 31 { 32 if(f[s[1][now]-'A']+f[s[2][now]-'A']==f[s[3][now]-'A']+n)dfs(now+1,0); 33 if(judge&&f[s[1][now]-'A']+f[s[2][now]-'A']+1==f[s[3][now]-'A']+n)dfs(now+1,1); 34 } 35 else 36 { 37 if(f[s[1][now]-'A']+f[s[2][now]-'A']==f[s[3][now]-'A'])dfs(now+1,0); 38 if(judge&&f[s[1][now]-'A']+f[s[2][now]-'A']+1==f[s[3][now]-'A'])dfs(now+1,1); 39 } 40 return; 41 } 42 if(f[s[1][now]-'A']!=-1&&f[s[2][now]-'A']==-1&&f[s[3][now]-'A']==-1) 43 { 44 for(int i=0;i<n;i++) 45 if(!used[i]) 46 { 47 used[i]=1,f[s[2][now]-'A']=i; 48 dfs(now,jinwei); 49 used[i]=0,f[s[2][now]-'A']=-1; 50 } 51 return ; 52 } 53 if(f[s[1][now]-'A']==-1&&f[s[2][now]-'A']!=-1&&f[s[3][now]-'A']==-1) 54 { 55 for(int i=0;i<n;i++) 56 if(!used[i]) 57 { 58 used[i]=1,f[s[1][now]-'A']=i; 59 dfs(now,jinwei); 60 used[i]=0,f[s[1][now]-'A']=-1; 61 } 62 return ; 63 } 64 65 if(f[s[1][now]-'A']==-1&&f[s[2][now]-'A']==-1&&f[s[3][now]-'A']!=-1) 66 { 67 for(int i=0;i<n;i++) 68 if(!used[i]) 69 { 70 used[i]=1,f[s[1][now]-'A']=i; 71 dfs(now,jinwei); 72 used[i]=0,f[s[1][now]-'A']=-1; 73 } 74 return ; 75 } 76 if(f[s[1][now]-'A']!=-1&&f[s[2][now]-'A']==-1&&f[s[3][now]-'A']!=-1) 77 { 78 int c=f[s[3][now]-'A']-f[s[1][now]-'A']; 79 if(!c) 80 { 81 if(!used[0]&&!jinwei) 82 { 83 used[0]=1,f[s[2][now]-'A']=0; 84 dfs(now+1,0); 85 used[0]=0,f[s[2][now]-'A']=-1; 86 } 87 if(!used[1]&&!jinwei) 88 { 89 used[1]=1,f[s[2][now]-'A']=1; 90 dfs(now+1,1); 91 used[1]=0,f[s[2][now]-'A']=-1; 92 } 93 if(!used[n-1]&&jinwei) 94 { 95 used[n-1]=1,f[s[2][now]-'A']=n-1; 96 dfs(now+1,1); 97 used[n-1]=0,f[s[2][now]-'A']=-1; 98 } 99 } 100 if(c<0) 101 { 102 if(!jinwei)return; 103 if(!used[c+n]) 104 { 105 int val=f[s[3][now]-'A']+n-f[s[1][now]-'A']; 106 used[val]=1,f[s[2][now]-'A']=val; 107 dfs(now+1,0); 108 used[val]=0,f[s[2][now]-'A']=-1; 109 } 110 if(judge&&!used[c+n-1]) 111 { 112 int val=f[s[3][now]-'A']+n-f[s[1][now]-'A']-1; 113 used[val]=1,f[s[2][now]-'A']=val; 114 dfs(now+1,1); 115 used[val]=0,f[s[2][now]-'A']=-1; 116 } 117 } 118 if(c>0) 119 { 120 if(jinwei)return; 121 if(!used[c%n]) 122 { 123 int val=f[s[3][now]-'A']-f[s[1][now]-'A']; 124 used[val]=1,f[s[2][now]-'A']=val; 125 dfs(now+1,0); 126 used[val]=0,f[s[2][now]-'A']=-1; 127 } 128 if(judge&&!used[(c-1)%n]) 129 { 130 int val=f[s[3][now]-'A']-f[s[1][now]-'A']-1; 131 used[val]=1,f[s[2][now]-'A']=val; 132 dfs(now+1,1); 133 used[val]=0,f[s[2][now]-'A']=-1; 134 } 135 } 136 return; 137 } 138 if(f[s[1][now]-'A']==-1&&f[s[2][now]-'A']!=-1&&f[s[3][now]-'A']!=-1) 139 { 140 int c=f[s[3][now]-'A']-f[s[2][now]-'A']; 141 if(!c) 142 { 143 if(!used[0]&&!jinwei) 144 { 145 used[0]=1,f[s[1][now]-'A']=0; 146 dfs(now+1,0); 147 used[0]=0,f[s[1][now]-'A']=-1; 148 } 149 if(!used[1]&&!jinwei) 150 { 151 used[1]=1,f[s[1][now]-'A']=1; 152 dfs(now+1,1); 153 used[1]=0,f[s[1][now]-'A']=-1; 154 } 155 if(!used[n-1]&&jinwei) 156 { 157 used[n-1]=1,f[s[1][now]-'A']=n-1; 158 dfs(now+1,1); 159 used[n-1]=0,f[s[1][now]-'A']=-1; 160 } 161 } 162 if(c<0) 163 { 164 if(!jinwei)return; 165 if(!used[c+n]) 166 { 167 int val=f[s[3][now]-'A']+n-f[s[2][now]-'A']; 168 used[val]=1,f[s[1][now]-'A']=val; 169 dfs(now+1,0); 170 used[val]=0,f[s[1][now]-'A']=-1; 171 } 172 if(judge&&!used[c+n-1]) 173 { 174 int val=f[s[3][now]-'A']+n-f[s[2][now]-'A']-1; 175 used[val]=1,f[s[1][now]-'A']=val; 176 dfs(now+1,1); 177 used[val]=0,f[s[1][now]-'A']=-1; 178 } 179 } 180 if(c>0) 181 { 182 if(jinwei)return; 183 if(!used[c%n]) 184 { 185 int val=f[s[3][now]-'A']-f[s[2][now]-'A']; 186 used[val]=1,f[s[1][now]-'A']=val; 187 dfs(now+1,0); 188 used[val]=0,f[s[1][now]-'A']=-1; 189 } 190 if(judge&&!used[(c-1)%n]) 191 { 192 int val=f[s[3][now]-'A']-f[s[2][now]-'A']-1; 193 used[val]=1,f[s[1][now]-'A']=val; 194 dfs(now+1,1); 195 used[val]=0,f[s[1][now]-'A']=-1; 196 } 197 } 198 return; 199 } 200 if(f[s[1][now]-'A']!=-1&&f[s[2][now]-'A']!=-1&&f[s[3][now]-'A']==-1) 201 { 202 if(jinwei) 203 { 204 if(f[s[1][now]-'A']+f[s[2][now]-'A']<n-1)return; 205 if(!used[(f[s[1][now]-'A']+f[s[2][now]-'A']+1)%n]) 206 { 207 int val=(f[s[1][now]-'A']+f[s[2][now]-'A']+1)%n; 208 f[s[3][now]-'A']=val,used[val]=1; 209 dfs(now+1,1); 210 f[s[3][now]-'A']=-1,used[val]=0; 211 } 212 if(f[s[1][now]-'A']+f[s[2][now]-'A']>=n&&!used[(f[s[1][now]-'A']+f[s[2][now]-'A'])%n]) 213 { 214 int val=(f[s[1][now]-'A']+f[s[2][now]-'A'])%n; 215 f[s[3][now]-'A']=val,used[val]=1; 216 dfs(now+1,0); 217 f[s[3][now]-'A']=-1,used[val]=0; 218 } 219 } 220 else 221 { 222 if(f[s[1][now]-'A']+f[s[2][now]-'A']>=n)return; 223 if(!used[f[s[1][now]-'A']+f[s[2][now]-'A']]) 224 { 225 int val=f[s[1][now]-'A']+f[s[2][now]-'A']; 226 f[s[3][now]-'A']=val,used[val]=1; 227 dfs(now+1,0); 228 f[s[3][now]-'A']=-1,used[val]=0; 229 } 230 if(judge&&(f[s[1][now]-'A']+f[s[2][now]-'A']<n)&&!used[f[s[1][now]-'A']+f[s[2][now]-'A']+1]) 231 { 232 int val=f[s[1][now]-'A']+f[s[2][now]-'A']+1; 233 f[s[3][now]-'A']=val,used[val]=1; 234 dfs(now+1,1); 235 f[s[3][now]-'A']=-1,used[val]=0; 236 } 237 } 238 } 239 return; 240 } 241 int haha() 242 { 243 freopen("alpha.in","r",stdin); 244 freopen("alpha.out","w",stdout); 245 scanf("%d",&n);memset(f,-1,sizeof(f)); 246 for(int i=1;i<4;i++)scanf("%s",s[i]+1); 247 dfs(1,0);while(1); 248 } 249 int sb=haha(); 250 int main(){;}
燈:链接:http://cogs.pro/cogs/problem/problem.php?pid=539
首先通过撕烤,我们可以发现每一个节点情况都可以由各个与之相连的情况转移过来,由于每个节点都只有灯亮和灯灭两种情况,因此问题就变成了解异或方程组。但是这样做会出现一个小问题:有些自由元最终结果是无关本身但是与其他东西有关的,因此我们改变策略,解方程只解到消元这一步,之后回带继续分类讨论……自由元分类讨论其他根据自由元得解……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=35; 7 int a[maxn][maxn],b[maxn],x[maxn],n,m,freedom[maxn],ans=0x7fffffff; 8 void dfs(int now,int tmp) 9 { 10 if(tmp>ans)return; 11 if(now<=0){ans=min(ans,tmp);return;} 12 if(freedom[now]) 13 { 14 x[now]=1;dfs(now-1,tmp+1); 15 x[now]=0;dfs(now-1,tmp); 16 } 17 else 18 { 19 x[now]=b[now]; 20 for(int j=now+1;j<=n;j++) 21 if(a[now][j])x[now]^=x[j]; 22 dfs(now-1,tmp+x[now]); 23 } 24 } 25 void gauss() 26 { 27 for(int k=1;k<=n;k++) 28 { 29 for(int i=k;i<=n;i++) 30 if(a[i][k]) 31 { 32 if(i!=k) 33 { 34 for(int j=k;j<=n;j++)swap(a[i][j],a[k][j]); 35 swap(b[i],b[k]); 36 } 37 break; 38 } 39 if(!a[k][k]){freedom[k]=1;continue;} 40 for(int i=k+1;i<=n;i++) 41 { 42 if(!a[i][k])continue; 43 for(int j=k;j<=n;j++)a[i][j]^=a[k][j]; 44 b[i]^=b[k]; 45 } 46 } 47 } 48 int haha() 49 { 50 freopen("lights.in","r",stdin); 51 freopen("lights.out","w",stdout); 52 scanf("%d%d",&n,&m); 53 for(int i=1;i<=n;i++)a[i][i]=b[i]=1; 54 for(int i=1;i<=m;i++) 55 { 56 int x,y;scanf("%d%d",&x,&y); 57 a[x][y]=a[y][x]=1; 58 } 59 gauss();dfs(n,0);printf("%d\n",ans); 60 } 61 int sb=haha(); 62 int main(){;}
新数独:链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3109
首先,给出的这些限制条件就相当于给出了我们一些天然的限制条件,于是我们就可以剪枝更加愉快啦……然后就是个靶形数独……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<vector> 6 using namespace std; 7 typedef pair<int,int>pii; 8 const int v[10][10]={ 9 {0}, 10 {0,1,1,1,2,2,2,3,3,3}, 11 {0,1,1,1,2,2,2,3,3,3}, 12 {0,1,1,1,2,2,2,3,3,3}, 13 {0,4,4,4,5,5,5,6,6,6}, 14 {0,4,4,4,5,5,5,6,6,6}, 15 {0,4,4,4,5,5,5,6,6,6}, 16 {0,7,7,7,8,8,8,9,9,9}, 17 {0,7,7,7,8,8,8,9,9,9}, 18 {0,7,7,7,8,8,8,9,9,9} 19 },to[]={0,1,2,4,5,7,8},pos[]={0,1,1,2,2,3,4,4,5,5,6,7,7,8,8,9}; 20 char s[16][10]; 21 int rudu[10][10],chudu[10][10],num[10][10],guanxi[10][10][10][10],shutot; 22 bool used[10][10],heng[10][10],shu[10][10]; 23 void addedge(int u,int v,int x,int y) 24 { 25 rudu[u][v]++,chudu[x][y]++,guanxi[u][v][x][y]=1,guanxi[x][y][u][v]=-1; 26 } 27 bool check(int x,int y,int numm) 28 { 29 if(x>1&&num[x-1][y]) 30 { 31 if(guanxi[x][y][x-1][y]==1&&numm>=num[x-1][y])return 0; 32 if(guanxi[x][y][x-1][y]==-1&&numm<=num[x-1][y])return 0; 33 } 34 if(x<9&&num[x+1][y]) 35 { 36 if(guanxi[x][y][x+1][y]==1&&numm>=num[x+1][y])return 0; 37 if(guanxi[x][y][x+1][y]==-1&&numm<=num[x+1][y])return 0; 38 } 39 if(y>1&&num[x][y-1]) 40 { 41 if(guanxi[x][y][x][y-1]==1&&numm>=num[x][y-1])return 0; 42 if(guanxi[x][y][x][y-1]==-1&&numm<=num[x][y-1])return 0; 43 } 44 if(y<9&&num[x][y+1]) 45 { 46 if(guanxi[x][y][x][y+1]==1&&numm>=num[x][y+1])return 0; 47 if(guanxi[x][y][x][y+1]==-1&&numm<=num[x][y+1])return 0; 48 } 49 return 1; 50 } 51 void dfs(int ro,int co) 52 { 53 if(ro>9) 54 { 55 for(int i=1;i<=9;i++) 56 { 57 for(int j=1;j<=9;j++) 58 { 59 if(j>=2) putchar(' '); 60 printf("%d",num[i][j]); 61 } 62 puts(""); 63 } 64 exit(0); 65 } 66 for(int i=chudu[ro][co]+1;i<10-rudu[ro][co];i++) 67 { 68 if(used[v[ro][co]][i]||heng[ro][i]||shu[co][i])continue; 69 if(!check(ro,co,i))continue; 70 used[v[ro][co]][i]=heng[ro][i]=shu[co][i]=1;num[ro][co]=i;dfs(ro+((co%9)?0:1),co%9?co+1:1); 71 used[v[ro][co]][i]=heng[ro][i]=shu[co][i]=0;num[ro][co]=0; 72 } 73 } 74 int haha() 75 { 76 for(int i=1;i<=15;i++) 77 { 78 int j=0;char c=getchar(); 79 while(c!='\n') 80 { 81 if(c!=' ')s[i][++j]=c; 82 c=getchar(); 83 } 84 } 85 for(int i=1;i<=15;i++) 86 if(((i%5)&1)||!(i%5)) 87 for(int j=1;j<=6;j++) 88 if(s[i][j]=='<')addedge(pos[i],to[j],pos[i],to[j]+1); 89 else addedge(pos[i],to[j]+1,pos[i],to[j]); 90 else 91 for(int j=1;j<=9;j++) 92 if(s[i][j]=='^')addedge(pos[i],j,pos[i]+1,j); 93 else addedge(pos[i]+1,j,pos[i],j); 94 dfs(1,1); 95 } 96 int sb=haha(); 97 int main(){;}
$phi$的反函数:出门掉头:http://www.cnblogs.com/Loser-of-Life/p/7537748.html
持续填坑中……