有一种恐怖,叫大爆搜

到目前这个阶段,大爆搜做了好几个,有必要做一下小的总结了。

玛雅游戏:出门左转 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$,运用贪心策略选择最长线段进行覆盖。

 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(){;}
cogs521

 靶形数独:链接:http://cogs.pro/cogs/problem/problem.php?pid=407

说好的状压启发式搜索呢?怎么是裸的$dfs$?虽然我很喜欢……港真,我今天下午颓了半下午这道题样例……和$wcx$比赛数独结果对面最后还剩两步发现他全错……欢声笑语中打出$GG$……

 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(){;}
cogs407

传染病控制:链接:http://cogs.pro/cogs/problem/problem.php?pid=107

果然$CCF$老爷机啊……正常情况下每一次都是要剪枝的,但是在评测机上直接裸$dfs$,每一层暴力判断,改都不改就过了……

 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(){;}
cogs107

字串变换:链接:http://cogs.pro/cogs/problem/problem.php?pid=65

这果然是那个没有$STL$的时代啊……原来可是要$Hash$加$Treap$判重的,现在$std::queue$、$std::queue$、$std::map$、$std::string$直接碾压……除去这些,就是一个双向广搜。

 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(){;}
cogs65

我回来一定要总结$std::string$来骗一波访问量(有生之年系列)

栅栏:链接:http://cogs.pro/cogs/problem/problem.php?pid=882

神之思路……首先显然可以证明这个选择木板的数量是具有单调性的……于是我们二分答案……二分之后问题就变成是否存在一种方式使这个数量木板被锯出来……然后里面有一些神之剪枝……感性理解一下

 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 }
cogs882

寻找道路:链接:http://cogs.pro/cogs/problem/problem.php?pid=1807

首先构建出反图,$dfs$找到每一个可以直接或者间接连接到终点的点,然后正向$dfs$搞出来每一个点是否所有出边都可以连接终点……之后就用这些点里面的边跑最短路……

 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(){;}
cogs1807

 文化之旅:链接:http://cogs.pro/cogs/problem/problem.php?pid=1271

看上去是个搜索……然而$Floyd$过了……数据太水……=  =

 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(){;}
cogs1271

虫食算:链接:http://cogs.pro/cogs/problem/problem.php?pid=69

大型分类讨论……我比较蠢写了$8$种情况……再加上并没有随时定义变量减少码量……结果就导致$250$行代码长度$7.8K$……=  =码长基本没有超过我的了……写的奇蠢无比凑合看吧……

  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(){;}
cogs69

 燈:链接:http://cogs.pro/cogs/problem/problem.php?pid=539

首先通过撕烤,我们可以发现每一个节点情况都可以由各个与之相连的情况转移过来,由于每个节点都只有灯亮和灯灭两种情况,因此问题就变成了解异或方程组。但是这样做会出现一个小问题:有些自由元最终结果是无关本身但是与其他东西有关的,因此我们改变策略,解方程只解到消元这一步,之后回带继续分类讨论……自由元分类讨论其他根据自由元得解……

 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(){;}
cogs539

新数独:链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3109

首先,给出的这些限制条件就相当于给出了我们一些天然的限制条件,于是我们就可以剪枝更加愉快啦……然后就是个靶形数独……

 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(){;}
bzoj3109

$phi$的反函数:出门掉头:http://www.cnblogs.com/Loser-of-Life/p/7537748.html

持续填坑中……

posted @ 2017-09-17 20:29  ccc000111  阅读(324)  评论(0编辑  收藏  举报