算法-蓝桥杯习题(四)

蓝桥杯习题

蓝桥杯练习系统习题加答案更新新地址(已更新200左右习题)

http://blog.csdn.net/rodestillfaraway 

 


 

目录

算法训练(详见 算法-蓝桥杯习题(一))Go

算法训练(详见 算法-蓝桥杯习题(二))Go

算法提高(waiting...)

历届试题(详见 算法-蓝桥杯习题(六))Go

历届试题(详见 算法-蓝桥杯习题(七))Go

 


 

蓝桥杯练习系统评测数据

链接:

http://pan.baidu.com/s/1mhophTQ

密码: m2pa

 


 

算法提高(PartA-10题)

 

  1 /*
  2 算法提高 两条直线
  3 
  4 问题描述
  5 给定平面上n个点。
  6 
  7 求两条直线,这两条直线互相垂直,而且它们与x轴的夹角为45度,并且n个点中离这两条直线的曼哈顿距离的最大值最小。
  8 
  9 两点之间的曼哈顿距离定义为横坐标的差的绝对值与纵坐标的差的绝对值之和,一个点到两条直线的曼哈顿距离是指该点到两条直线上的所有点的曼哈顿距离中的最小值。
 10 
 11 输入格式
 12 第一行包含一个数n。
 13 
 14 接下来n行,每行包含两个整数,表示n个点的坐标(横纵坐标的绝对值小于109)。
 15 
 16 输出格式
 17 输出一个值,表示最小的最大曼哈顿距离的值,保留一位小数。
 18 样例输入
 19 4
 20 1 0
 21 0 1
 22 2 1
 23 1 2
 24 样例输出
 25 1.0
 26 数据规模与约定
 27 对于30%的数据,n<=100。
 28 
 29 对于另外30%的数据,坐标范的绝对值小于100。
 30 
 31 对于100%的数据,n<=10的5次方。
 32 
 33 */
 34 #include<iostream>
 35 #include<algorithm>
 36 #include<cstdio>
 37 #include<cmath>
 38 using namespace std;
 39 
 40 const int N=100000;
 41 struct P{int x,y;};
 42 bool cmp(P a,P b){
 43     if(a.x==b.x)return a.y<b.y;
 44     return a.x<b.x;
 45 }
 46 P d[N+5];
 47 struct F{int max,min;};
 48 F fl[N+5],fr[N+5];
 49 inline double Max(double a,double b){return a>b?a:b;}
 50 inline double Min(double a,double b){return a>b?b:a;}
 51 bool check(double m,int n){
 52     m*=2;
 53     int i,j=0;
 54     for(i=0;i<n;i++){
 55         while(j<n&&d[j].x-d[i].x<=m)j++;
 56         double MAX=-1e10;
 57         double MIN=1e10;
 58         if(j!=n){
 59             MAX=Max(MAX,fr[j].max);
 60             MIN=Min(MIN,fr[j].min);
 61         }
 62         if(i-1>=0){
 63             MAX=Max(MAX,fl[i-1].max);
 64             MIN=Min(MIN,fl[i-1].min);
 65         }
 66      //   cout<<i<<" "<<j<<" "<<MAX<<" "<<MIN<<endl;
 67         if(MAX-MIN<=m)return true;
 68     }
 69     return false;
 70 }
 71 void init(int n){
 72     int i;
 73     fl[0].min=fl[0].max=d[0].y;
 74     for(i=1;i<n;i++){
 75         fl[i].max=Max(fl[i-1].max,d[i].y);
 76         fl[i].min=Min(fl[i-1].min,d[i].y);
 77     }
 78     fr[n-1].min=fr[n-1].max=d[n-1].y;
 79     for(i=n-2;i>=0;i--){
 80         fr[i].max=Max(fr[i+1].max,d[i].y);
 81         fr[i].min=Min(fr[i+1].min,d[i].y);
 82     }
 83 }
 84 int main(){
 85     int i,n;
 86     cin>>n;
 87     for(i=0;i<n;i++){
 88         int x,y;
 89         scanf("%d%d",&x,&y);
 90         d[i].x=x+y;
 91         d[i].y=x-y;
 92     }
 93     sort(d,d+n,cmp);
 94     init(n);
 95     double l=0.0;
 96     double r=1000000000;
 97     while(r-l>=0.01){
 98         double m=(l+r)/2;
 99       //  cout<<m<<endl;
100         if(check(m,n))r=m;
101         else l=m;
102     }
103     printf("%.1f\n",r);
104     return 0;
105 }

 

 1 /*
 2 算法提高 矩阵翻转
 3 
 4 问题描述
 5 Ciel有一个N*N的矩阵,每个格子里都有一个整数。
 6 
 7 N是一个奇数,设X = (N+1)/2。Ciel每次都可以做这样的一次操作:他从矩阵选出一个X*X的子矩阵,并将这个子矩阵中的所有整数都乘以-1。
 8 
 9 现在问你经过一些操作之后,矩阵中所有数的和最大可以为多少。
10 
11 输入格式
12 第一行为一个正整数N。
13 
14 接下来N行每行有N个整数,表示初始矩阵中的数字。每个数的绝对值不超过1000。
15 
16 输出格式
17 输出一个整数,表示操作后矩阵中所有数之和的最大值。
18 样例输入
19 3
20 -1 -1 1
21 -1 1 -1
22 1 -1 -1
23 样例输出
24 9
25 数据规模与约定
26 1 <= N <= 33,且N为奇数。
27 */
28 #include<stdio.h>
29 int x[33][33],ans,N;
30 void fun1(int n)
31 {
32     int i,j,lin=0,aa,bb;
33     for(j=0;j<N;j++)
34         lin+=x[n-1][j];
35     for(i=0;i<n-1;i++)
36     {
37         aa=-1000000000;
38         bb=x[i][n-1]+x[i+n][n-1];
39         for(j=0;j<n-1;j++)
40             bb+=abs(x[i][j]+x[i+n][j]+x[i][j+n]+x[i+n][j+n]);
41         aa=aa>bb?aa:bb;
42         bb=-x[i][n-1]-x[i+n][n-1];
43         for(j=0;j<n-1;j++)
44             bb+=abs(-x[i][j]-x[i+n][j]+x[i][j+n]+x[i+n][j+n]);
45         aa=aa>bb?aa:bb;
46         lin+=aa;
47     }
48     ans=ans>lin?ans:lin;
49 }
50 void fun(int n)
51 {
52     int i,j,k;
53     for(k=0;k<(1<<n-1);k++)
54     {
55         for(i=0;i<n-1;i++)
56             if((k&(1<<i))!=0)
57                 for(j=0;j<n;j++)
58                 {
59                     x[j][i]*=-1;
60                     x[j][i+n]*=-1;
61                 }
62         fun1(n);
63         for(i=0;i<n-1;i++)
64             if((k&(1<<i))!=0)
65                 for(j=0;j<n;j++)
66                 {
67                     x[j][i]*=-1;
68                     x[j][i+n]*=-1;
69                 }
70     }
71 }
72 int main(void)
73 {
74     int i,j,k;
75     scanf("%d",&N);
76     for(i=0;i<N;i++)
77         for(j=0;j<N;j++)
78             scanf("%d",&x[i][j]);
79     k=(N+1)/2;
80     ans=-1000000000;
81     fun(k);
82     for(i=0;i<k;i++)
83         for(j=0;j<k;j++)
84             x[i][j]=-x[i][j];
85     fun(k);
86     printf("%d\n",ans);
87     return 0;
88 }
  1 /*
  2 算法提高 金属采集
  3 
  4 问题描述
  5 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了。一些节点之间有道路相连,所有的节点和道路形成了一棵树。一共有 n 个节点,这些节点被编号为 1~n 。人类将 k 个机器人送上了火星,目的是采集这些金属。这些机器人都被送到了一个指定的着落点, S 号节点。每个机器人在着落之后,必须沿着道路行走。当机器人到达一个节点时,它会采集这个节点蕴藏的所有金属矿。当机器人完成自己的任务之后,可以从任意一个节点返回地球。当然,回到地球的机器人就无法再到火星去了。我们已经提前测量出了每条道路的信息,包括它的两个端点 x 和 y,以及通过这条道路需要花费的能量 w 。我们想花费尽量少的能量采集所有节点的金属,这个任务就交给你了。
  6 
  7 输入格式
  8 第一行包含三个整数 n, S 和 k ,分别代表节点个数、着落点编号,和机器人个数。
  9 
 10 接下来一共 n-1 行,每行描述一条道路。一行含有三个整数 x, y 和 w ,代表在 x 号节点和 y 号节点之间有一条道路,通过需要花费 w 个单位的能量。所有道路都可以双向通行。
 11 
 12 输出格式
 13 输出一个整数,代表采集所有节点的金属所需要的最少能量。
 14 样例输入
 15 6 1 3
 16 1 2 1
 17 2 3 1
 18 2 4 1000
 19 2 5 1000
 20 1 6 1000
 21 样例输出
 22 3004
 23 样例说明
 24 所有机器人在 1 号节点着陆。
 25 
 26 第一个机器人的行走路径为 1->6 ,在 6 号节点返回地球,花费能量为1000。
 27 
 28 第二个机器人的行走路径为 1->2->3->2->4 ,在 4 号节点返回地球,花费能量为1003。
 29 
 30 第一个机器人的行走路径为 1->2->5 ,在 5 号节点返回地球,花费能量为1001。
 31 
 32 数据规模与约定
 33 本题有10个测试点。
 34 
 35 对于测试点 1~2 , n <= 10 , k <= 5 。
 36 
 37 对于测试点 3 , n <= 100000 , k = 1 。
 38 
 39 对于测试点 4 , n <= 1000 , k = 2 。
 40 
 41 对于测试点 5~6 , n <= 1000 , k <= 10 。
 42 
 43 对于测试点 7~10 , n <= 100000 , k <= 10 。
 44 
 45 道路的能量 w 均为不超过 1000 的正整数。
 46 */
 47 #include <iostream>
 48 #include <cstdio>
 49 using namespace std;
 50 
 51 const int MAXN=100000+10,oo=100000000,MAXK=10+1;
 52 
 53 typedef long long LL;
 54 
 55 int N,S,K,fa[MAXN];
 56 int g[MAXN],num[MAXN*2],next[MAXN*2],cost[MAXN*2],tot=1;
 57 LL f[MAXN][MAXK],sum;
 58 
 59 inline void read(int &x)
 60 {
 61   char ch;
 62   while (ch=getchar(),ch>'9' || ch<'0') ; x=ch-48;
 63   while (ch=getchar(),ch<='9' && ch>='0') x=x*10+ch-48;
 64 }
 65 
 66 inline void addedge(int a,int b,int c) { ++tot; num[tot]=b; next[tot]=g[a]; g[a]=tot; cost[tot]=c; }
 67 
 68 void dfs(int x)
 69 {
 70   for (int i=g[x];i;i=next[i])
 71     if (num[i]!=fa[x])
 72     {
 73       fa[num[i]]=x;
 74       dfs(num[i]);
 75       
 76       for (int a=K;a;--a)
 77         for (int b=1;b<=a;++b)
 78           f[x][a]=max(f[x][a],f[x][a-b]+f[num[i]][b]+(LL)(-b+2)*cost[i]);
 79     }
 80 }
 81 
 82 int main()
 83 {
 84   read(N); read(S); read(K);
 85   for (int i=1;i<N;++i)
 86   {
 87     int x,y,z;
 88     read(x); read(y); read(z); sum+=z;
 89     addedge(x,y,z); addedge(y,x,z);
 90   }
 91   
 92   sum=sum+sum;
 93   dfs(S);
 94   
 95   LL ans=oo; ans=ans*ans;
 96   for (int i=0;i<=K;++i) ans=min(ans,sum-f[S][i]);
 97   
 98   cout << ans << endl;
 99   
100   return 0;
101 }
  1 /*
  2 算法提高 道路和航路
  3 
  4 问题描述
  5 农夫约翰正在针对一个新区域的牛奶配送合同进行研究。他打算分发牛奶到T个城镇(标号为1..T),这些城镇通过R条标号为(1..R)的道路和P条标号为(1..P)的航路相连。
  6 
  7 每一条公路i或者航路i表示成连接城镇Ai(1<=A_i<=T)和Bi(1<=Bi<=T)代价为Ci。每一条公路,Ci的范围为0<=Ci<=10,000;由于奇怪的运营策略,每一条航路的Ci可能为负的,也就是-10,000<=Ci<=10,000。
  8 
  9 每一条公路都是双向的,正向和反向的花费是一样的,都是非负的。
 10 
 11 每一条航路都根据输入的Ai和Bi进行从Ai->Bi的单向通行。实际上,如果现在有一条航路是从Ai到Bi的话,那么意味着肯定没有通行方案从Bi回到Ai。
 12 
 13 农夫约翰想把他那优良的牛奶从配送中心送到各个城镇,当然希望代价越小越好,你可以帮助他嘛?配送中心位于城镇S中(1<=S<=T)。
 14 
 15 输入格式
 16 输入的第一行包含四个用空格隔开的整数T,R,P,S。
 17 
 18 接下来R行,描述公路信息,每行包含三个整数,分别表示Ai,Bi和Ci。
 19 
 20 接下来P行,描述航路信息,每行包含三个整数,分别表示Ai,Bi和Ci。
 21 
 22 输出格式
 23 输出T行,分别表示从城镇S到每个城市的最小花费,如果到不了的话输出NO PATH。
 24 样例输入
 25 6 3 3 4
 26 1 2 5
 27 3 4 5
 28 5 6 10
 29 3 5 -100
 30 4 6 -100
 31 1 3 -10
 32 样例输出
 33 NO PATH
 34 NO PATH
 35 5
 36 0
 37 -95
 38 -100
 39 数据规模与约定
 40 对于20%的数据,T<=100,R<=500,P<=500;
 41 
 42 对于30%的数据,R<=1000,R<=10000,P<=3000;
 43 
 44 对于100%的数据,1<=T<=25000,1<=R<=50000,1<=P<=50000。
 45 */
 46 #include <iostream>
 47 #include <cstdio>
 48 #include <cstring>
 49 #include <algorithm>
 50 #include <queue>
 51 #include <stack>
 52 #include <vector>
 53 
 54 #define clr(a,b) memset(a, b, sizeof(a))
 55 
 56 using namespace std;
 57 
 58 const int N = 25050;
 59 const int E = 150500;
 60 
 61 //邻接表
 62 int h[N], v[E], w[E], nxt[E], el;
 63 void initEdge() {
 64     clr(h, -1); el = 0;
 65 }
 66 void addEdge(int x, int y, int z) {
 67     v[el] = y; w[el] = z; nxt[el] = h[x]; h[x] = el++;
 68 }
 69 
 70 //belong[i] 表示节点 i 所在的强连通分量;
 71 //cnt 表示强连通分量的个数;
 72 int dfn[N], sta[N], low[N], belong[N];
 73 int top, cnt, ind, n;
 74 bool vis[N];
 75 
 76 void TarjanSolve(int u) {
 77     dfn[u] = low[u] = ++ind;
 78     vis[u] = true;
 79     sta[++top] = u;
 80     for(int p=h[u]; ~p; p=nxt[p]) {
 81         int i = v[p];
 82         if(!dfn[i]) {
 83             TarjanSolve(i);
 84             if(low[i] < low[u]) low[u] = low[i];
 85         }
 86         else
 87         if(vis[i] && dfn[i] < low[u])
 88             low[u] = dfn[i];
 89     }
 90     if(dfn[u] == low[u]) {
 91         ++cnt;
 92         while(1) {
 93             int i = sta[top--];
 94             vis[i] = false;
 95             belong[i] = cnt;
 96             if(i == u) break;
 97         }
 98     }
 99 }
100 void Tarjan() {//注意节点是从几开始存的
101     clr(dfn, 0);
102     clr(vis, 0);
103     top = cnt = ind = 0;
104     for(int i=1; i<=n; i++)//这里节点从1开始存,若从0开始存要改这里
105         if(!dfn[i]) TarjanSolve(i);
106 }
107 
108 struct EDGE {
109     int u, v, w;
110     bool flag;
111     EDGE(){}
112     EDGE(int x, int y, int z, bool f):u(x), v(y), w(z), flag(f){}
113 }   edge[E];
114 
115 int edgel;
116 
117 bool visitable[N];
118 
119 void dfs(int x) {
120     visitable[x] = true;
121     for(int i=h[x]; ~i; i=nxt[i]) {
122         if(!visitable[v[i]]) {
123             dfs(v[i]);
124         }
125     }
126 }
127 
128 int indegree[N];
129 
130 //链表
131 int lh[N], lel, lv[E], lnxt[E];
132 void initLink() {
133     clr(lh, -1); lel = 0;
134 }
135 void addLink(int x, int y) {
136     lv[lel] = y; lnxt[lel] = lh[x]; lh[x] = lel++;
137 }
138 
139 int dis[N];
140 bool tag[N];
141 
142 int main() {
143     int r, p, s;
144     while(~scanf("%d%d%d%d", &n, &r, &p, &s)) {
145         clr(visitable, 0);
146         initEdge();
147         edgel = 0;
148         int x, y, z;
149         for(int i=0; i<r; i++) {
150             scanf("%d%d%d", &x, &y, &z);
151             addEdge(x, y, z);
152             addEdge(y, x, z);
153             edge[edgel++] = EDGE(x, y, z, false);
154         }
155         for(int i=0; i<p; i++) {
156             scanf("%d%d%d", &x, &y, &z);
157             addEdge(x, y, z);
158             edge[edgel++] = EDGE(x, y, z, true);
159         }
160         Tarjan();
161         dfs(s);
162         initEdge();
163         initLink();
164         clr(indegree, 0);
165         for(int i=0; i<edgel; i++) {
166             if(visitable[edge[i].u] && visitable[edge[i].v]) {
167                 addEdge(edge[i].u, edge[i].v, edge[i].w);
168                 if(edge[i].flag) {
169                     ++ indegree[belong[edge[i].v]];
170                     addLink(belong[edge[i].v], edge[i].v);
171                 } else {
172                     addEdge(edge[i].v, edge[i].u, edge[i].w);
173                 }
174             }
175         }
176         stack<int> zeroDegree;
177         priority_queue<pair<int,int> > que;
178         clr(vis, false);
179         clr(tag, false);
180         clr(dis, 0x3f);
181         dis[s] = 0;
182         que.push(make_pair(0, s));
183         while(!que.empty() || !zeroDegree.empty()) {
184             if(que.empty()) {
185                 int x = zeroDegree.top(); zeroDegree.pop();
186                 for(int i=lh[x]; ~i; i=lnxt[i]) {
187                     int y = lv[i];
188                     if(!vis[y]) {
189                         vis[y] = true;
190                         que.push(make_pair(-dis[y], y));
191                     }
192                 }
193             } else {
194                 int x = que.top().second; que.pop();
195                 if(tag[x]) continue;
196                 tag[x]  = true;
197                 for(int i=h[x]; ~i; i=nxt[i]) {
198                     int y = v[i];
199                     if(!tag[y] && dis[y] > dis[x] + w[i]) {
200                         dis[y] = dis[x] + w[i];
201                         if(belong[x] == belong[y]) {
202                             que.push(make_pair(-dis[y], y));
203                         }
204                     }
205                     if(belong[x] != belong[y]) {
206                         -- indegree[belong[y]];
207                         if(indegree[belong[y]] == 0) {
208                             zeroDegree.push(belong[y]);
209                         }
210                     }
211                 }
212             }
213         }
214         for(int i=1; i<=n; i++) {
215             if(visitable[i]) {
216                 printf("%d\n", dis[i]);
217             } else {
218                 puts("NO PATH");
219             }
220         }
221     }
222 
223     return 0;
224 }
  1 /*
  2 算法提高 道路和航路
  3 
  4 问题描述
  5 农夫约翰正在针对一个新区域的牛奶配送合同进行研究。他打算分发牛奶到T个城镇(标号为1..T),这些城镇通过R条标号为(1..R)的道路和P条标号为(1..P)的航路相连。
  6 
  7 每一条公路i或者航路i表示成连接城镇Ai(1<=A_i<=T)和Bi(1<=Bi<=T)代价为Ci。每一条公路,Ci的范围为0<=Ci<=10,000;由于奇怪的运营策略,每一条航路的Ci可能为负的,也就是-10,000<=Ci<=10,000。
  8 
  9 每一条公路都是双向的,正向和反向的花费是一样的,都是非负的。
 10 
 11 每一条航路都根据输入的Ai和Bi进行从Ai->Bi的单向通行。实际上,如果现在有一条航路是从Ai到Bi的话,那么意味着肯定没有通行方案从Bi回到Ai。
 12 
 13 农夫约翰想把他那优良的牛奶从配送中心送到各个城镇,当然希望代价越小越好,你可以帮助他嘛?配送中心位于城镇S中(1<=S<=T)。
 14 
 15 输入格式
 16 输入的第一行包含四个用空格隔开的整数T,R,P,S。
 17 
 18 接下来R行,描述公路信息,每行包含三个整数,分别表示Ai,Bi和Ci。
 19 
 20 接下来P行,描述航路信息,每行包含三个整数,分别表示Ai,Bi和Ci。
 21 
 22 输出格式
 23 输出T行,分别表示从城镇S到每个城市的最小花费,如果到不了的话输出NO PATH。
 24 样例输入
 25 6 3 3 4
 26 1 2 5
 27 3 4 5
 28 5 6 10
 29 3 5 -100
 30 4 6 -100
 31 1 3 -10
 32 样例输出
 33 NO PATH
 34 NO PATH
 35 5
 36 0
 37 -95
 38 -100
 39 数据规模与约定
 40 对于20%的数据,T<=100,R<=500,P<=500;
 41 
 42 对于30%的数据,R<=1000,R<=10000,P<=3000;
 43 
 44 对于100%的数据,1<=T<=25000,1<=R<=50000,1<=P<=50000。
 45 */
 46 #include <iostream>
 47 #include <cstdio>
 48 #include <cstring>
 49 #include <algorithm>
 50 #include <queue>
 51 #include <stack>
 52 #include <vector>
 53 
 54 #define clr(a,b) memset(a, b, sizeof(a))
 55 
 56 using namespace std;
 57 
 58 const int N = 25050;
 59 const int E = 150500;
 60 
 61 //邻接表
 62 int h[N], v[E], w[E], nxt[E], el;
 63 void initEdge() {
 64     clr(h, -1); el = 0;
 65 }
 66 void addEdge(int x, int y, int z) {
 67     v[el] = y; w[el] = z; nxt[el] = h[x]; h[x] = el++;
 68 }
 69 
 70 //belong[i] 表示节点 i 所在的强连通分量;
 71 //cnt 表示强连通分量的个数;
 72 int dfn[N], sta[N], low[N], belong[N];
 73 int top, cnt, ind, n;
 74 bool vis[N];
 75 
 76 void TarjanSolve(int u) {
 77     dfn[u] = low[u] = ++ind;
 78     vis[u] = true;
 79     sta[++top] = u;
 80     for(int p=h[u]; ~p; p=nxt[p]) {
 81         int i = v[p];
 82         if(!dfn[i]) {
 83             TarjanSolve(i);
 84             if(low[i] < low[u]) low[u] = low[i];
 85         }
 86         else
 87         if(vis[i] && dfn[i] < low[u])
 88             low[u] = dfn[i];
 89     }
 90     if(dfn[u] == low[u]) {
 91         ++cnt;
 92         while(1) {
 93             int i = sta[top--];
 94             vis[i] = false;
 95             belong[i] = cnt;
 96             if(i == u) break;
 97         }
 98     }
 99 }
100 void Tarjan() {//注意节点是从几开始存的
101     clr(dfn, 0);
102     clr(vis, 0);
103     top = cnt = ind = 0;
104     for(int i=1; i<=n; i++)//这里节点从1开始存,若从0开始存要改这里
105         if(!dfn[i]) TarjanSolve(i);
106 }
107 
108 struct EDGE {
109     int u, v, w;
110     bool flag;
111     EDGE(){}
112     EDGE(int x, int y, int z, bool f):u(x), v(y), w(z), flag(f){}
113 }   edge[E];
114 
115 int edgel;
116 
117 bool visitable[N];
118 
119 void dfs(int x) {
120     visitable[x] = true;
121     for(int i=h[x]; ~i; i=nxt[i]) {
122         if(!visitable[v[i]]) {
123             dfs(v[i]);
124         }
125     }
126 }
127 
128 int indegree[N];
129 
130 //链表
131 int lh[N], lel, lv[E], lnxt[E];
132 void initLink() {
133     clr(lh, -1); lel = 0;
134 }
135 void addLink(int x, int y) {
136     lv[lel] = y; lnxt[lel] = lh[x]; lh[x] = lel++;
137 }
138 
139 int dis[N];
140 bool tag[N];
141 
142 int main() {
143     int r, p, s;
144     while(~scanf("%d%d%d%d", &n, &r, &p, &s)) {
145         clr(visitable, 0);
146         initEdge();
147         edgel = 0;
148         int x, y, z;
149         for(int i=0; i<r; i++) {
150             scanf("%d%d%d", &x, &y, &z);
151             addEdge(x, y, z);
152             addEdge(y, x, z);
153             edge[edgel++] = EDGE(x, y, z, false);
154         }
155         for(int i=0; i<p; i++) {
156             scanf("%d%d%d", &x, &y, &z);
157             addEdge(x, y, z);
158             edge[edgel++] = EDGE(x, y, z, true);
159         }
160         Tarjan();
161         dfs(s);
162         initEdge();
163         initLink();
164         clr(indegree, 0);
165         for(int i=0; i<edgel; i++) {
166             if(visitable[edge[i].u] && visitable[edge[i].v]) {
167                 addEdge(edge[i].u, edge[i].v, edge[i].w);
168                 if(edge[i].flag) {
169                     ++ indegree[belong[edge[i].v]];
170                     addLink(belong[edge[i].v], edge[i].v);
171                 } else {
172                     addEdge(edge[i].v, edge[i].u, edge[i].w);
173                 }
174             }
175         }
176         stack<int> zeroDegree;
177         priority_queue<pair<int,int> > que;
178         clr(vis, false);
179         clr(tag, false);
180         clr(dis, 0x3f);
181         dis[s] = 0;
182         que.push(make_pair(0, s));
183         while(!que.empty() || !zeroDegree.empty()) {
184             if(que.empty()) {
185                 int x = zeroDegree.top(); zeroDegree.pop();
186                 for(int i=lh[x]; ~i; i=lnxt[i]) {
187                     int y = lv[i];
188                     if(!vis[y]) {
189                         vis[y] = true;
190                         que.push(make_pair(-dis[y], y));
191                     }
192                 }
193             } else {
194                 int x = que.top().second; que.pop();
195                 if(tag[x]) continue;
196                 tag[x]  = true;
197                 for(int i=h[x]; ~i; i=nxt[i]) {
198                     int y = v[i];
199                     if(!tag[y] && dis[y] > dis[x] + w[i]) {
200                         dis[y] = dis[x] + w[i];
201                         if(belong[x] == belong[y]) {
202                             que.push(make_pair(-dis[y], y));
203                         }
204                     }
205                     if(belong[x] != belong[y]) {
206                         -- indegree[belong[y]];
207                         if(indegree[belong[y]] == 0) {
208                             zeroDegree.push(belong[y]);
209                         }
210                     }
211                 }
212             }
213         }
214         for(int i=1; i<=n; i++) {
215             if(visitable[i]) {
216                 printf("%d\n", dis[i]);
217             } else {
218                 puts("NO PATH");
219             }
220         }
221     }
222 
223     return 0;
224 }
 1 /*
 2 算法提高 最小方差生成树 
 3 
 4 问题描述
 5 给定带权无向图,求出一颗方差最小的生成树。
 6 输入格式
 7 输入多组测试数据。第一行为N,M,依次是点数和边数。接下来M行,每行三个整数U,V,W,代表连接U,V的边,和权值W。保证图连通。n=m=0标志着测试文件的结束。
 8 输出格式
 9 对于每组数据,输出最小方差,四舍五入到0.01。输出格式按照样例。
10 样例输入
11 4 5
12 1 2 1
13 2 3 2
14 3 4 2
15 4 1 1
16 2 4 3
17 4 6
18 1 2 1
19 2 3 2
20 3 4 3
21 4 1 1
22 2 4 3
23 1 3 3
24 0 0
25 样例输出
26 Case 1: 0.22
27 Case 2: 0.00
28 数据规模与约定
29 1<=U,V<=N<=50,N-1<=M<=1000,0<=W<=50。数据不超过5组。
30 */
31 
32 //无答案求解答 
 1 /*
 2 算法提高 邮票面值设计
 3 
 4 问题描述
 5   给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤13)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1~MAX之间的每一个邮资值都能得到。
 6 
 7   例如,N=3,K=2,如果面值分别为1分、4分,则在1分~6分之间的每一个邮资值都能得到(当然还有8分、9分和12分);如果面值分别为1分、3分,则在1分~7分之间的每一个邮资值都能得到。可以验证当N=3,K=2时,7分就是可以得到的连续的邮资最大值,所以MAX=7,面值分别为1分、3分。
 8 输入格式
 9   一行,两个数N、K
10 输出格式
11   两行,第一行升序输出设计的邮票面值,第二行输出“MAX=xx”(不含引号),其中xx为所求的能得到的连续邮资最大值。
12 样例输入
13 3 2
14 样例输出
15 1 3
16 MAX=7
17 */
18 #include <stdio.h>
19 #define M 500
20 int a[20],f[M],ans[20];
21 int N,K,MAX,g=1<<29;
22 void DFS(int k,int s){    
23 int i,j,t[M];    
24 if (k==K)    
25 {        
26 if (s>=MAX)           
27  for (MAX=s,i=1;i<=K;i++) 
28  ans[i]=a[i];        
29  return;    
30  }    
31  for (i=0;i<M;i++) 
32  t[i]=f[i];    
33  for (i=a[k]+1;i<=s;i++)    
34  {        
35  for (j=0;j<M-i;j++)            
36  if (f[j]+1<f[j+i]) 
37  f[j+i]=f[j]+1;       
38   for (j=s;f[j]<=N;j++);       
39    a[k+1]=i;       
40     DFS(k+1,j);       
41      for (j=0;j<M;j++) f[j]=t[j];   
42       }}
43       int main(){   
44        int i;    
45        scanf("%d%d",&N,&K);   
46         a[1]=1;   
47          for (i=1;i<=N;i++) 
48          f[i]=i;   
49           for (;i<M;i++) 
50           f[i]=g;   
51            DFS(1,N+1);   
52             for (i=1;i<=K;i++) 
53             printf("%d ",ans[i]);  
54               printf("\nMAX=%d",MAX-1);   
55                return 0;
56 }
 1 /*
 2 算法提高 子集选取
 3 
 4 问题描述
 5   一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007。
 6 输入格式
 7   输入一行两个整数N,K。
 8 输出格式
 9   输出一个整数表示答案。
10 样例输入
11 3 2
12 样例输出
13 6
14 数据规模和约定
15   1 <= K <= N <= 10 ^ 6。
16 */
17 
18 //No Answer 
  1 /*
  2 算法提高 冒泡排序计数
  3 
  4 考虑冒泡排序的一种实现。
  5   bubble-sort (A[], n)
  6   > round = 0
  7   > while A is not sorted
  8   > > round := round + 1
  9   > > for i := 1 to n - 1
 10   > > > if (A[i] > A[i + 1])
 11   > > > > swap(A[i], A[i + 1])
 12   求1 .. n的排列中,有多少个排列使得A被扫描了K遍,亦即算法结束时round == K。
 13 
 14   答案模20100713输出。
 15 输入格式
 16   输入包含多组数据。每组数据为一行两个整数N,K。
 17 输出格式
 18   对每组数据,输出一行一个整数表示答案。
 19 样例输入
 20 3
 21 3 0
 22 3 1
 23 3 2
 24 样例输出
 25 1
 26 3
 27 2
 28 数据规模和约定
 29   T <= 10 ^ 5。
 30   1 <= K < N < 10 ^ 6。
 31 */
 32 #define OUTPUT_PRECISION    "%.2f"
 33 #define LF_PRECISION        10
 34 #define INT_64_MOD          "%I64d"
 35 #define UNSIGNED_64_MOD     "%I64u"
 36 
 37 #include<cmath>
 38 #include<cstdio>
 39 #include<cstdlib>
 40 #include<cstring>
 41 #include<algorithm>
 42 #include<bitset>
 43 #include<complex>
 44 #include<vector>
 45 #include<iomanip>
 46 #include<iostream>
 47 #include<list>
 48 #include<map>
 49 #include<queue>
 50 #include<set>
 51 #include<stack>
 52 #include<string>
 53 #include<typeinfo>
 54 #define FAST_RW ios_base::sync_with_stdio(0),cin.tie(0);
 55 #define IT(x) __typeof((x).begin())
 56 #define FS(i,a) for(ll i=0;a[i];i++)
 57 #define FE(x,ctn) for(IT(ctn)x=(ctn).begin(),CluhxSchFuDeugk=(ctn).end();x!=CluhxSchFuDeugk;x++)
 58 #define FR(i,en) for(ll i=0,pJNwFPtlXiwFoIv=(en);i<pJNwFPtlXiwFoIv;i++)
 59 #define FOR(i,en) for(ll i=1,SbKCIcakJTeYVqs=(en);i<=SbKCIcakJTeYVqs;i++)
 60 #define FFR(i,x,y) for(ll i=(x),alVDbhLBoMEGSwA=(y);i<=alVDbhLBoMEGSwA;i++)
 61 #define DFFR(i,x,y) for(ll i=(x),NWYfecAcmGBMJuU=(y);i>=NWYfecAcmGBMJuU;i--)
 62 #define ll long long
 63 #define ull unsigned long long
 64 #define lf long double
 65 #define pc putchar
 66 #define mp make_pair
 67 #define pb push_back
 68 #define pq priority_queue
 69 #define fi first
 70 #define se second
 71 #define pii pair<int,int>
 72 #define pdd pair<double,double>
 73 #define lb(x) (x&(-x))
 74 #define sqr(x) (x)*(x)
 75 #define all(x) (x).begin(),(x).end()
 76 #define clr(x) memset((x),0,sizeof(x))
 77 #define ms(x,v) memset((x),(v),sizeof(x))
 78 #define mc(x,y) memcpy((x),(y),sizeof(y))
 79 #define NL puts("");
 80 #define fin(x,c) ((c).find(x)!=(c).end())
 81 using namespace std;
 82 
 83 template<class T1,class T2,class T3>
 84 bool _IN(T1 x,T2 y,T3 z){
 85   return x<=y&&x>=z||x<=z&&x>=y;
 86 }
 87 
 88 ull gcd(ull a,ull b){
 89   if(!b)return a;
 90   while(b^=a^=b^=a%=b);
 91   return a;
 92 }
 93 
 94 #ifdef wmx16835
 95 #define NOT_TESTING_TEMPLATE_CPP
 96 #include"wmx16835.cpp"
 97 
 98 #else
 99 int ebtpqJsBCnTgggi;
100 #define LOG {
101 #define TEL }
102 #define SHOW_TIME
103 #define test(...) ebtpqJsBCnTgggi
104 #define TEST(...) ebtpqJsBCnTgggi
105 #define TRY(...)
106 #define PF
107 #define PP ;
108 #endif
109 
110 bool S(char*a){
111   return scanf("%s",a)==1;
112 }
113 
114 char DATaJNTFnlmAoya[2];
115 
116 template<class T>
117 bool S(T&a){
118   const char*x=typeid(a).name();
119   if(!strcmp(x,"i")||!strcmp(x,"b"))return scanf("%d",&a)==1;
120   else if(!strcmp(x,"j"))return scanf("%u",&a)==1;
121   else if(!strcmp(x,"c")){
122     if(scanf("%1s",DATaJNTFnlmAoya)==-1)
123       return 0;
124     a=*DATaJNTFnlmAoya;
125     return 1;
126   }
127   else if(!strcmp(x,"Pc")||*x=='A')return scanf("%s",a)==1;
128   else if(!strcmp(x,"f"))return scanf("%f",&a)==1;
129   else if(!strcmp(x,"d"))return scanf("%lf",&a)==1;
130   else if(!strcmp(x,"x"))return scanf(INT_64_MOD,&a)==1;
131   else if(!strcmp(x,"y"))return scanf(UNSIGNED_64_MOD,&a)==1;
132   else if(!strcmp(x,"e"))return (cin>>a)!=0;
133   else test("Input format error!\n");
134 }
135 
136 void _P(string x){
137   printf("%s",x.c_str());
138 }
139 
140 template<class T>
141 void _P(T a){
142   const char*x=typeid(a).name();
143   if(!strcmp(x,"i")||!strcmp(x,"b"))printf("%d",a);
144   else if(!strcmp(x,"j"))printf("%u",a);
145   else if(!strcmp(x,"c"))printf("%c",a);
146   else if(!strcmp(x,"Pc")||!strcmp(x,"PKc")||*x=='A')printf("%s",a);
147   else if(!strcmp(x,"d")||!strcmp(x,"f"))printf(OUTPUT_PRECISION,a);
148   else if(!strcmp(x,"x"))printf(INT_64_MOD,a);
149   else if(!strcmp(x,"y"))printf(UNSIGNED_64_MOD,a);
150   else if(!strcmp(x,"e"))cout<<setprecision(LF_PRECISION)<<a;
151   else test("Output format error!\n");
152 }
153 
154 template<class T1,class T2>
155 bool S(T1&a,T2&b){
156   return S(a)+S(b)==2;
157 }
158 
159 template<class T1,class T2,class T3>
160 bool S(T1&a,T2&b,T3&c){
161   return S(a)+S(b)+S(c)==3;
162 }
163 
164 template<class T1,class T2,class T3,class T4>
165 bool S(T1&a,T2&b,T3&c,T4&d){
166   return S(a)+S(b)+S(c)+S(d)==4;
167 }
168 
169 template<class T1,class T2,class T3,class T4,class T5>
170 bool S(T1&a,T2&b,T3&c,T4&d,T5&e){
171   return S(a)+S(b)+S(c)+S(d)+S(e)==5;
172 }
173 
174 template<class T>
175 void P(T a){
176   _P(a);
177   pc(' ');
178 }
179 
180 template<class T1,class T2>
181 void P(T1 a,T2 b){
182   _P(a);pc(' ');
183   _P(b);pc(' ');
184 }
185 
186 template<class T>
187 void PN(T a){
188   _P(a);
189   NL
190 }
191 
192 template<class T1,class T2>
193 void PN(T1 a,T2 b){
194   _P(a);pc(' ');
195   _P(b);NL
196 }
197 
198 template<class T1,class T2,class T3>
199 void PN(T1 a,T2 b,T3 c){
200   _P(a);pc(' ');
201   _P(b);pc(' ');
202   _P(c);NL
203 }
204 
205 template<class T1,class T2,class T3,class T4>
206 void PN(T1 a,T2 b,T3 c,T4 d){
207   _P(a);pc(' ');
208   _P(b);pc(' ');
209   _P(c);pc(' ');
210   _P(d);NL
211 }
212 
213 template<class T1,class T2,class T3,class T4,class T5>
214 void PN(T1 a,T2 b,T3 c,T4 d,T5 e){
215   _P(a);pc(' ');
216   _P(b);pc(' ');
217   _P(c);pc(' ');
218   _P(d);pc(' ');
219   _P(e);NL
220 }
221 
222 template<class T>
223 void PA(T*a,int n,char c=' '){
224   FR(i,n-1)_P(a[i]),pc(c);
225   PN(a[n-1]);
226 }
227 
228 template<class T>
229 void PA(const T&x,char c=' '){
230   IT(x) ita=x.begin();
231   FE(it,x){
232     _P(*it);
233     if(++ita==x.end())NL
234     else pc(c);
235   }
236 }
237 
238 int kase;
239 const double pi=4*atan(1);
240 const double ep=1e-9;
241 //}
242 
243 ll mod=20100713;
244 
245 ll jc[1000005];
246 
247 void init(){
248   jc[0]=1;
249   FOR(i,1000000)
250     jc[i]=i*jc[i-1]%mod;
251 }
252 
253 ll ksm(ll x,int t){
254   ll res=1,tmp=x;
255   while(t){
256     if(t&1)res=res*tmp%mod;
257     tmp=tmp*tmp%mod;
258     t>>=1;
259   }
260   return res;
261 }
262 
263 int main(){
264   SHOW_TIME
265   init();
266   int t;
267   S(t);
268   while(t--){
269     ll n,k;
270     S(n,k);
271     ll res=jc[k]*ksm(k+1,n-k)-jc[k-1]*ksm(k,n-k+1);
272     PN((res%mod+mod)%mod);
273   }
274 }
 1 /*
 2 算法提高 递归倒置字符数组
 3 
 4 问题描述
 5   完成一个递归程序,倒置字符数组。并打印实现过程
 6   递归逻辑为:
 7   当字符长度等于1时,直接返回
 8   否则,调换首尾两个字符,在递归地倒置字符数组的剩下部分
 9 输入格式
10   字符数组长度及该数组
11 输出格式
12   在求解过程中,打印字符数组的变化情况。
13   最后空一行,在程序结尾处打印倒置后该数组的各个元素。
14 样例输入
15 Sample 1
16 5 abcde
17 Sample 2
18 1 a
19 
20 样例输出
21 
22 
23 Sample 1
24 ebcda
25 edcba
26 edcba
27 Sample 2
28 a
29 */
30 #include<stdio.h>
31 #include<string.h>
32 
33 void digui(char *c,int top,int end)
34 {
35     char tmp;
36     if(top==end)
37         return;
38     if(top<end)
39     {
40         tmp=c[top];
41         c[top]=c[end];
42         c[end]=tmp;
43         puts(c);
44         digui(c,top+1,end-1);
45     }
46 }
47 
48 int main(void)
49 {
50     char c[1000];
51     int n;
52     scanf("%d",&n);
53     getchar();
54     gets(c);
55     digui(c,0,n-1);
56     printf("\n");
57     puts(c);
58     return 0;
59 }
  1 /*
  2 算法提高 立方体截断问题
  3 
  4 问题描述
  5   如右图所示,这是一个空心正方体(请想象用纸糊出来的正方体),每条棱的编号如图所示
  6   (图在http://166.111.138.150/fop/attach/cube.jpg)。
  7 
  8   考虑剪开若干条棱,请判断正方体是否会被剪成分开(即判断正方体是否会被分割成不少于2个部分)。
  9 输入格式
 10   本题包括多组数据。
 11   第一行输入一个N,表示数据组数。
 12   对于每一组数据,都包括两行。
 13   第一行输入一个n,表示总共剪开了n条棱。
 14   第二行有n个数,每个数表示剪开的棱的编号。(输入保证每条棱出现次数不超过1)
 15 输出格式
 16   对于每一组输入,输出一行。
 17   若正方体会被分割成不少于2个部分,则输出“Yes”,否则输出“No”(均不包括引号)。
 18 样例输入
 19 5
 20 4
 21 1 2 3 4
 22 6
 23 1 2 5 7 11 12
 24 3
 25 1 4 5
 26 6
 27 1 3 4 5 9 12
 28 12
 29 1 2 3 4 5 6 7 8 9 10 11 12
 30 
 31 样例输出
 32 
 33 
 34 Yes
 35 Yes
 36 No
 37 No
 38 Yes
 39 */
 40 
 41 
 42 #define OUTPUT_PRECISION    "%.2f"
 43 #define LF_PRECISION        10
 44 #define INT_64_MOD          "%lld"
 45 #define UNSIGNED_64_MOD     "%llu"
 46 
 47 //#pragma comment(linker,"/STACK:102400000,102400000")
 48 #include<cmath>
 49 #include<cstdio>
 50 #include<cstdlib>
 51 #include<cstring>
 52 #include<algorithm>
 53 #include<bitset>
 54 #include<complex>
 55 #include<vector>
 56 #include<iomanip>
 57 #include<iostream>
 58 #include<list>
 59 #include<map>
 60 #include<queue>
 61 #include<set>
 62 #include<stack>
 63 #include<string>
 64 #include<typeinfo>
 65 #define FAST_RW ios_base::sync_with_stdio(0),cin.tie(0);
 66 #define IT(x) __typeof((x).begin())
 67 #define FS(i,a) for(ll i=0;a[i];i++)
 68 #define FE(x,ctn) for(IT(ctn)x=(ctn).begin(),CluhxSchFuDeugk=(ctn).end();x!=CluhxSchFuDeugk;x++)
 69 #define FR(i,en) for(ll i=0,pJNwFPtlXiwFoIv=(en);i<pJNwFPtlXiwFoIv;i++)
 70 #define FOR(i,en) for(ll i=1,SbKCIcakJTeYVqs=(en);i<=SbKCIcakJTeYVqs;i++)
 71 #define FFR(i,x,y) for(ll i=(x),alVDbhLBoMEGSwA=(y);i<=alVDbhLBoMEGSwA;i++)
 72 #define DFFR(i,x,y) for(ll i=(x),NWYfecAcmGBMJuU=(y);i>=NWYfecAcmGBMJuU;i--)
 73 #define ll long long
 74 #define ull unsigned long long
 75 #define lf long double
 76 #define pc putchar
 77 #define mp make_pair
 78 #define pb push_back
 79 #define pq priority_queue
 80 #define fi first
 81 #define se second
 82 #define pii pair<int,int>
 83 #define pdd pair<double,double>
 84 #define lb(x) (x&(-x))
 85 #define sqr(x) (x)*(x)
 86 #define all(x) (x).begin(),(x).end()
 87 #define clr(x) memset((x),0,sizeof(x))
 88 #define ms(x,v) memset((x),(v),sizeof(x))
 89 #define mc(x,y) memcpy((x),(y),sizeof(y))
 90 #define NL puts("");
 91 #define fin(x,c) ((c).find(x)!=(c).end())
 92 using namespace std;
 93 
 94 template<class T1,class T2,class T3>
 95 bool _IN(T1 x,T2 y,T3 z){
 96   return x<=y&&x>=z||x<=z&&x>=y;
 97 }
 98 
 99 ull gcd(ull a,ull b){
100   if(!b)return a;
101   while(b^=a^=b^=a%=b);
102   return a;
103 }
104 
105 #ifdef wmx16835
106 #define NOT_TESTING_TEMPLATE_CPP
107 #include"wmx16835.cpp"
108 
109 #else
110 int ebtpqJsBCnTgggi;
111 #define LOG {
112 #define TEL }
113 #define SHOW_TIME
114 #define test(...) ebtpqJsBCnTgggi
115 #define TEST(...) ebtpqJsBCnTgggi
116 #define TRY(...)
117 #define PF
118 #define PP ;
119 #endif
120 
121 bool S(char*a){
122   return scanf("%s",a)==1;
123 }
124 
125 char DATaJNTFnlmAoya[2];
126 
127 template<class T>
128 bool S(T&a){
129   const char*x=typeid(a).name();
130   if(!strcmp(x,"i")||!strcmp(x,"b"))return scanf("%d",&a)==1;
131   else if(!strcmp(x,"j"))return scanf("%u",&a)==1;
132   else if(!strcmp(x,"c")){
133     if(scanf("%1s",DATaJNTFnlmAoya)==-1)
134       return 0;
135     a=*DATaJNTFnlmAoya;
136     return 1;
137   }
138   else if(!strcmp(x,"Pc")||*x=='A')return scanf("%s",a)==1;
139   else if(!strcmp(x,"f"))return scanf("%f",&a)==1;
140   else if(!strcmp(x,"d"))return scanf("%lf",&a)==1;
141   else if(!strcmp(x,"x"))return scanf(INT_64_MOD,&a)==1;
142   else if(!strcmp(x,"y"))return scanf(UNSIGNED_64_MOD,&a)==1;
143   else if(!strcmp(x,"e"))return (cin>>a)!=0;
144   else test("Input format error!\n");
145 }
146 
147 void _P(string x){
148   printf("%s",x.c_str());
149 }
150 
151 template<class T>
152 void _P(T a){
153   const char*x=typeid(a).name();
154   if(!strcmp(x,"i")||!strcmp(x,"b"))printf("%d",a);
155   else if(!strcmp(x,"j"))printf("%u",a);
156   else if(!strcmp(x,"c"))printf("%c",a);
157   else if(!strcmp(x,"Pc")||!strcmp(x,"PKc")||*x=='A')printf("%s",a);
158   else if(!strcmp(x,"d")||!strcmp(x,"f"))printf(OUTPUT_PRECISION,a);
159   else if(!strcmp(x,"x"))printf(INT_64_MOD,a);
160   else if(!strcmp(x,"y"))printf(UNSIGNED_64_MOD,a);
161   else if(!strcmp(x,"e"))cout<<setprecision(LF_PRECISION)<<a;
162   else test("Output format error!\n");
163 }
164 
165 template<class T1,class T2>
166 bool S(T1&a,T2&b){
167   return S(a)+S(b)==2;
168 }
169 
170 template<class T1,class T2,class T3>
171 bool S(T1&a,T2&b,T3&c){
172   return S(a)+S(b)+S(c)==3;
173 }
174 
175 template<class T1,class T2,class T3,class T4>
176 bool S(T1&a,T2&b,T3&c,T4&d){
177   return S(a)+S(b)+S(c)+S(d)==4;
178 }
179 
180 template<class T1,class T2,class T3,class T4,class T5>
181 bool S(T1&a,T2&b,T3&c,T4&d,T5&e){
182   return S(a)+S(b)+S(c)+S(d)+S(e)==5;
183 }
184 
185 template<class T>
186 void P(T a){
187   _P(a);
188   pc(' ');
189 }
190 
191 template<class T1,class T2>
192 void P(T1 a,T2 b){
193   _P(a);pc(' ');
194   _P(b);pc(' ');
195 }
196 
197 template<class T>
198 void PN(T a){
199   _P(a);
200   NL
201 }
202 
203 template<class T1,class T2>
204 void PN(T1 a,T2 b){
205   _P(a);pc(' ');
206   _P(b);NL
207 }
208 
209 template<class T1,class T2,class T3>
210 void PN(T1 a,T2 b,T3 c){
211   _P(a);pc(' ');
212   _P(b);pc(' ');
213   _P(c);NL
214 }
215 
216 template<class T1,class T2,class T3,class T4>
217 void PN(T1 a,T2 b,T3 c,T4 d){
218   _P(a);pc(' ');
219   _P(b);pc(' ');
220   _P(c);pc(' ');
221   _P(d);NL
222 }
223 
224 template<class T1,class T2,class T3,class T4,class T5>
225 void PN(T1 a,T2 b,T3 c,T4 d,T5 e){
226   _P(a);pc(' ');
227   _P(b);pc(' ');
228   _P(c);pc(' ');
229   _P(d);pc(' ');
230   _P(e);NL
231 }
232 
233 template<class T>
234 void PA(T*a,int n,char c=' '){
235   FR(i,n-1)_P(a[i]),pc(c);
236   PN(a[n-1]);
237 }
238 
239 template<class T>
240 void PA(const T&x,char c=' '){
241   IT(x) ita=x.begin();
242   FE(it,x){
243     _P(*it);
244     if(++ita==x.end())NL
245     else pc(c);
246   }
247 }
248 
249 int kase;
250 const double pi=4*atan(1);
251 const double ep=1e-9;
252 //}
253 
254 int a[]={0,1,2,2,2,1,1,3,3,1,4,3,5};
255 int b[]={0,2,4,3,6,6,4,4,6,5,5,5,6};
256 bool av[15];
257 
258 int fa[8];
259 
260 int f(int x){
261   return x==fa[x]?x:fa[x]=f(fa[x]);
262 }
263 
264 void unite(int x,int y){
265   fa[f(x)]=f(y);
266 }
267 
268 int main(){
269   SHOW_TIME
270   int t;
271   S(t);
272   while(t--){
273     FOR(i,6)fa[i]=i;
274     FOR(i,12)av[i]=1;
275     int n=0,m;
276     S(n);
277     while(n--){
278       S(m);
279       av[m]=0;
280     }
281     FOR(i,12){
282       if(av[i])unite(a[i],b[i]);
283     }
284     bool ok=1;
285     FOR(i,6)if(f(i)!=f(1)){
286       puts("Yes");
287       ok=0;
288       break;
289     }
290     if(ok)puts("No");
291   }
292 }

 

posted @ 2016-01-11 11:57  鬼狐  阅读(2182)  评论(0编辑  收藏  举报