Training Contest 1

好像是福建省赛。

FZU 2140 Forever 0.5

题意:叫你找满足条件的n个点。

做法:

n<=3的时候,输出no。n大于3,选一个等边三角形ABC,边长为1,然后剩下的n-3的点,就可以在AC弧 和 BC弧里面找。注意n等于4的时候, p[3] = point(sqrt(3.0)/2-0.5, 0.5);这样凸包的面积刚好是5,选其他点面积会小于5。画一画图就知道了。好像题目还可以输出重复的点。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 
 9 #define N 120
10 #define M 200020
11 #define LL long long
12 #define inf 0x3f3f3f3f
13 #define eps 1e-8
14 
15 int dcmp(double x){
16     if( fabs(x) < eps ) return 0;
17     return x < 0 ? -1 : 1;
18 }
19 struct point{
20     double x, y;
21     point(double x = 0, double y = 0) : x(x), y(y) {}
22     point operator + (const point &b) const {
23         return point(x + b.x, y + b.y);
24     }
25     point operator - (const point &b) const {
26         return point(x - b.x, y - b.y);
27     }
28     bool operator < (const point &b) const {
29         return dcmp(x - b.x) < 0 || dcmp(x - b.x) == 0 && dcmp(y - b.y) < 0;
30     }
31 };
32 point p[N], ch[N];
33 int n;
34 double calc2(double tmp){
35     double ret = 1 - (tmp+0.5)*(tmp+0.5);
36     return sqrt(ret);
37 }
38 double calc1(double tmp){
39     double ret = 1 - (tmp-0.5)*(tmp-0.5);
40     return sqrt(ret);
41 }
42 void solve( int L, int R ){
43     p[0] = point(0.5, 0), p[1] = point(-0.5, 0), p[2] = point(0, sqrt(3.0)/2);
44     int cnt = 3;
45     double len = -0.5 / (L + 1), tmp = len;
46     for(int i = 0; i < L; ++i, tmp += len){
47         double yy = calc1( tmp );
48         p[cnt++] = point(tmp, yy);
49     }
50     len = 0.5 / (R + 1), tmp = len;
51     for(int i = 0; i < R; ++i, tmp += len){
52         double yy = calc2( tmp );
53         p[cnt++] = point(tmp, yy);
54     }
55     if( cnt == 4 )
56         p[3] = point(sqrt(3.0)/2-0.5, 0.5);
57     puts( "Yes" );
58     for(int i = 0; i < cnt; ++i){
59         printf( "%.6lf %.6lf
", p[i].x, p[i].y );
60     }
61 }
62 int main(){
63     int cas, kk = 1;
64     scanf("%d", &cas);
65     while( cas-- ){
66         scanf("%d", &n);
67         if( n <= 3 ){
68             puts( "No" ); continue;
69         }
70         n -= 3;
71         int L = n / 2, R = n - L;
72         solve(L, R);
73     }
74     return 0;
75 }
View Code

FZU 2141 Sub-Bipartite Graph

题意:给出N个点M条边的图,现在要从中选出两个不相交的点集,使得以这两个点集构成的原图的子图构成一个二分图,并使得边数>=M/2。

做法:贪心,一个点一个点地染色。比如有一些染好的点,对于一个没染的点来说,它周围有x条边是连黑点,y条边是连白点,z条是没有连,那么看x > y就染白点,否则染黑点。这样其实是决定我们最后留的图里面是 留x个去掉y个,还是留y个去掉x个(z个不是在这个地方决定的,在后面别的点连这个点的时候决定的,我们就不用关心),因为我们选的是x和y中较大的那个,所以边数满足>= M/2。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<string>
 6 #include<queue>
 7 #include<vector>
 8 #include<cmath>
 9 
10 using namespace std;
11 
12 #define N 120
13 #define M 10200
14 #define LL long long
15 #define inf 0x3f3f3f3f
16 #define MP make_pair
17 #define lson l, m, rt << 1
18 #define rson m+1, r, rt << 1 | 1
19 #define mod 9973
20 
21 int fst[N], vv[M], nxt[M], e, col[N];
22 bool vis[N];
23 void init(){
24     memset(fst, -1, sizeof fst);
25     memset(col, 0, sizeof col);
26     memset(vis, 0, sizeof vis);
27     e = 0;
28 }
29 void add(int u, int v){
30     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
31 }
32 
33 void dfs(int u){
34     int aa = 0, bb = 0;
35     for(int i = fst[u]; i != -1; i = nxt[i]){
36         int v = vv[i];
37         if(col[v] == 1) aa++;
38         if(col[v] == 2) bb++;
39     }
40     if( aa > bb ) col[u] = 2;
41     else col[u] = 1;
42     vis[u] = 1;
43     for(int i = fst[u]; i != -1; i = nxt[i]){
44         int v = vv[i];
45         if(!vis[v])
46             dfs( v );
47     }
48 }
49 vector<int> g[3];
50 int main(){
51     //freopen("tt.txt", "r", stdin);
52     int cas;
53     scanf("%d", &cas);
54     while(cas--){
55         init();
56         g[1].clear(); g[2].clear();
57         int n, m;
58         scanf("%d%d", &n, &m);
59         for(int i = 0; i < m; ++i){
60             int u, v;
61             scanf("%d%d", &u, &v);
62             add(u, v), add(v, u);
63         }
64         for(int i = 1; i <= n; ++i)
65             if(!vis[i])
66                 dfs(i);
67         for(int i = 1; i <= n; ++i)
68             g[col[i]].push_back( i );
69         for(int i = 1; i < 3; ++i){
70             int tmp = g[i].size();
71             printf("%d", tmp);
72             for( int j = 0; j < tmp; ++j)
73                 printf(" %d", g[i][j]);
74             puts( "" );
75         }
76 
77     }
78     return 0;
79 }
View Code

FZU 2142 Center of a Tree

题意:给出n个点的树,问它的子树有多少和它有相同的中心。树中心是指使得距离树最远的点最近的点,中心有可能有1个或2个。

做法:树dp,看了别人的blog,这里。先求出树的中心,然后看树的中心有几个。如果有两个,就比较简单,只要让这两个中心的子树的最长距离相等就好了。如果只有一个,这种情况要求保证最长距离为k时,选出的子树中,至少有两个中心结点的儿子节点并且它们的最长距离为k。dp2[j][0],dp2[j][1],dp2[j][2]分别表示以前 j 个儿子结点构成的子树中,长度为k的子树有0个,1个,大于等于2个,那么可以写成状态转移方程:

dp2[j][0]=dp2[j-1][0]*(1+dp[v][i-1]);
dp2[j][1]=dp2[j-1][1]*(1+dp[v][i-1])+dp2[j-1][0]*(dp[v][i]-dp[v][i-1]);
dp2[j][2]=dp2[j-1][2]*(1+dp[v][i-1])+(dp2[j-1][1]+dp2[j-1][2])*(dp[v][i]-dp[v][i-1]);
最后加上答案就行了。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <algorithm>
  5 #include <cstring>
  6 #include <queue>
  7 
  8 using namespace std;
  9 
 10 #define N 1010
 11 #define M 2020
 12 #define LL long long
 13 #define inf 0x3f3f3f3f
 14 #define lson id << 1, l, m
 15 #define rson id << 1 | 1, m + 1, r
 16 #define mod 10086
 17 
 18 int fst[N], nxt[M], vv[M], e;
 19 void add(int u, int v){
 20     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
 21 }
 22 int son[N], dp[N][N], milen, res[2], dp2[N][4], g[N], kk = 1;
 23 void dfs1(int u, int p){    //dp[u][0]表示u所在的子树的最长的距离是多少,dp[u][1]表示u所在的子树的次长距离是多少
 24     dp[u][0] = dp[u][1] = 0;
 25     son[u] = 0;
 26     for(int i = fst[u]; i != -1; i = nxt[i]){
 27         int v = vv[i];
 28         if(v == p) continue;
 29         dfs1(v, u);
 30         if(dp[v][0] + 1 > dp[u][0]){
 31             dp[u][1] = dp[u][0];
 32             dp[u][0] = dp[v][0] + 1;
 33             son[u] = v;
 34         }
 35         else if(dp[v][0] + 1 > dp[u][1])
 36             dp[u][1] = dp[v][0] + 1;
 37     }
 38 }
 39 void dfs2(int u, int p, int mxlen){   //求树的中心。
 40     int tmp = max(mxlen, dp[u][0]);
 41     if(tmp < milen){
 42         milen = tmp;
 43         res[0] = u;
 44         res[1] = -1;
 45     }
 46     else if(tmp == milen)
 47         res[1] = u;
 48     for(int i = fst[u]; i != -1; i = nxt[i]){
 49         int v = vv[i];
 50         if(v == p) continue;
 51         if(v == son[u])
 52             tmp = dp[u][1] + 1;
 53         else tmp = dp[u][0] + 1;
 54         dfs2(v, u, max(mxlen + 1, tmp));
 55     }
 56 }
 57 void init(){
 58     e = 0, milen = inf;
 59     memset(fst, -1, sizeof fst);
 60     memset(son, 0, sizeof son);
 61 }
 62 int n;
 63 void dfs(int u, int p){    //dp[i][j]表示结点 i 在的子树中,距离i距离不超过j的方案数
 64     for(int i = 0; i <= n; ++i)
 65         dp[u][i] = 1;
 66     for(int i = fst[u]; i != -1; i = nxt[i]){
 67         int v = vv[i];
 68         if(v == p) continue;
 69         dfs(v, u);
 70         for(int i = 1; i <= n; ++i)
 71             dp[u][i] = (dp[u][i] + dp[u][i] * dp[v][i-1]) % mod;
 72     }
 73 }
 74 int mul[N];
 75 void solve(){
 76     dfs(res[0], res[1]);
 77     int ans = 1;
 78     if(res[1] != -1){  //如皋有两个中心,那么从两个中心点选距离为i的方案数。
 79         dfs(res[1], res[0]);
 80         for(int i = 1; i <= n; ++i){
 81             int tmp1 = dp[res[0]][i] - dp[res[0]][i-1];
 82             int tmp2 = dp[res[1]][i] - dp[res[1]][i-1];
 83             ans = (ans + tmp1 * tmp2) % mod;
 84         }
 85     }
 86     else{ //如皋只有一个中心。考虑res[0]的儿子结点。
 87         int cnt = 0;
 88         for(int i = fst[res[0]]; i != -1; i = nxt[i])
 89             g[++cnt] = vv[i];
 90         if(cnt > 1) ans = (ans + mul[cnt] - cnt - 1) % mod;
 91         dp2[0][0] = 1, dp2[0][1] = dp2[0][2] = 0;
 92         for(int i = 1; i <= n; ++i){
 93             for(int j = 1; j <= cnt; ++j){
 94                 dp2[j][0] = dp2[j-1][0] * (1 + dp[g[j]][i-1]) % mod;
 95                 dp2[j][1] = dp2[j-1][1] * (1 + dp[g[j]][i-1]) % mod + dp2[j-1][0] * (dp[g[j]][i] - dp[g[j]][i-1]) % mod;
 96                 dp2[j][2] = dp2[j-1][2] * (1 + dp[g[j]][i-1]) % mod + (dp2[j-1][1] + dp2[j-1][2]) * (dp[g[j]][i] - dp[g[j]][i-1]) % mod;
 97                 dp2[j][1] %= mod, dp2[j][2] %= mod;
 98             }
 99             ans = (ans + dp2[cnt][2]) % mod;
100         }
101     }
102     ans = (ans % mod + mod) % mod;
103     printf("Case %d: %d
", kk++, ans);
104 }
105 int main(){
106    // freopen("tt.txt", "r", stdin);
107     int cas;
108     mul[0] = 1;
109     for(int i = 1; i < N; ++i)
110         mul[i] = mul[i-1] * 2 % mod;
111     scanf("%d", &cas);
112     while(cas--){
113         init();
114         scanf("%d", &n);
115         for(int i = 1; i < n; ++i){
116             int u, v;
117             scanf("%d%d", &u, &v);
118             add(u, v), add(v, u);
119         }
120         dfs1(1, -1);
121         dfs2(1, -1, 0);
122         solve();
123     }
124 }
View Code

FZU 2143 Board Game

费用流。小坤子a了,好牛逼。

  1 /*
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <queue>
  7 using namespace std;
  8 
  9 #define N 120
 10 #define M 200020
 11 #define LL long long
 12 #define inf 0x3f3f3f3f
 13 #define eps 1e-8
 14 
 15 double x[mnx], y[mnx], n;
 16 void solve( int L, int R ){
 17     x[0] = 0.5, y[0] = 0;
 18     x[1] = -0.5, y[0] = 0;
 19     x[2] = 0, y[2] = sqrt(3.0) / 2;
 20     double len = 0.5 / ( L + 1 );
 21     for( int i = 0; i < L; ++i )
 22 }
 23 int main(){
 24     int cas, kk = 1;
 25     scanf("%d", &cas);
 26     while( cas-- ){
 27         scanf("%d", &n);
 28         if( n <= 3 ){
 29             puts( "No" ); continue;
 30         }
 31         puts( "Yes" );
 32         n -= 3;
 33         int L = n / 2, R = n - L;
 34         solve();
 35     }
 36     return 0;
 37 }
 38 */
 39 
 40 
 41 #include <iostream>
 42 #include <cstdio>
 43 #include <cstring>
 44 #include <algorithm>
 45 #include <queue>
 46 using namespace std;
 47 
 48 #define N 120
 49 #define M 200020
 50 #define LL long long
 51 #define inf 0x3f3f3f3f
 52 #define eps 1e-8
 53 
 54 
 55 struct edge {
 56     int u, v, cap, flow, cost, nxt;
 57     void set(int _u, int _v, int _cap, int _flow, int _cost, int _nxt) {
 58         u = _u, v = _v, cap = _cap, flow = _flow, cost = _cost, nxt = _nxt;
 59     }
 60 };
 61 
 62 struct mcmf {
 63     int fst[N], cc, d[N], p[N], a[N];
 64     edge e[M];
 65     bool in[N];
 66 
 67     void init() {
 68         memset(fst, -1, sizeof(fst)); cc = 0;
 69     }
 70     void add(int u, int v, int cap, int cost) {
 71         e[cc].set(u, v, cap, 0, cost, fst[u]), fst[u] = cc++;
 72         e[cc].set(v, u, 0, 0, -cost, fst[v]), fst[v] = cc++;
 73     }
 74     int spfa(int s, int t, int &mf, int &mc) {
 75         memset(d, 0x3f, sizeof(d));
 76         memset(in, 0, sizeof(in));
 77         d[s] = 0, a[s] = inf, in[s] = 1, p[s] = 0;
 78         queue<int> q; q.push(s);
 79         while(!q.empty()) {
 80             int u = q.front(); q.pop(); in[u] = 0;
 81             for(int i = fst[u]; ~i; i = e[i].nxt) {
 82                 int v = e[i].v;
 83                 if(e[i].cap > e[i].flow && d[v] > d[u] + e[i].cost) {
 84                     d[v] = d[u] + e[i].cost, p[v] = i;
 85                     a[v] = min(a[u], e[i].cap - e[i].flow);
 86                     if(!in[v]) in[v] = 1, q.push(v);
 87                 }
 88             }
 89         }
 90         if(d[t] == inf) return 0;
 91         mf += a[t], mc += a[t] * d[t];
 92         int u = t;
 93         while(u != s) {
 94             e[p[u]].flow += a[t], e[p[u] ^ 1].flow -= a[t];
 95             u = e[p[u]].u;
 96         }
 97         return 1;
 98     }
 99     int go(int s, int t) {
100         int ret = 0, mf = 0, mc = 0;
101         while(spfa(s, t, mf, mc)) {
102             ret = min(ret, mc);
103         }
104         return ret;
105     }
106 }go;
107 
108 int a[N][N];
109 int n, m, k;
110 int s, t;
111 int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
112 
113 int code(int x, int y) {
114     return (x - 1) * m + y;
115 }
116 int main() {
117     //freopen("tt.txt", "r", stdin);
118     int cas, kk = 0;
119     scanf("%d", &cas);
120     while(cas--) {
121         scanf("%d%d%d", &n, &m, &k);
122         go.init();
123         int sum = 0;
124         for(int i = 1; i <= n; ++i) {
125             for(int j = 1; j <= m; ++j) {
126                 scanf("%d", &a[i][j]);
127                 sum += a[i][j] * a[i][j];
128             }
129         }
130         s = 0, t = n * m + 1;
131         for(int i = 1; i <= n; ++i) {
132             for(int j = 1; j <= m; ++j) {
133                 int x = code(i, j);
134                 if((i + j) % 2 == 0) {
135                     for(int u = 1; u <= k; ++u) {
136                         go.add(s, x, 1, 2 * u - 1 - 2 * a[i][j]);
137                     }
138                     for(int u = 0; u < 4; ++u) {
139                         int di = i + dir[u][0];
140                         int dj = j + dir[u][1];
141                         if(di < 1 || dj < 1 || di > n || dj > m) continue;
142                         int y = code(di, dj);
143                         go.add(x, y, k, 0);
144                     }
145                 }
146                 else {
147                     for(int u = 1; u <= k; ++u)
148                         go.add(x, t, 1, 2 * u - 1 - 2 * a[i][j]);
149                 }
150             }
151         }
152         printf("Case %d: %d
", ++kk, sum + go.go(s, t));
153 
154     }
155     return 0;
156 }
View Code

FZU 2144 Shooting Game

题意:空间内有若干只蚊子,蚊子会朝着一个方向不停地飞,一个人站在原点拿着一把枪,他可以在任何时间开枪,每次他开枪,周围半径为r的球以内的蚊子会全部被射死,问他最多能射死多少蚊子,以及射死这么多蚊子所需用的最短时间。

做法:解二元一次方程。求出蚊子飞进球和飞出球的时间,然后排序,求有多少个不相交的区间。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 
 9 #define N 100020
10 #define M 2020
11 #define LL long long
12 #define inf 0x3f3f3f3f
13 #define eps 1e-8
14 #define mod 10086
15 
16 double RR;
17 int dcmp(double x){
18     if( fabs(x) < eps ) return 0;
19     return x < 0 ? -1 : 1;
20 }
21 struct node{
22     double L, R;
23     bool operator < (const node &b) const {
24         return dcmp(R - b.R) < 0;
25     }
26 }g[N];
27 void calc( double a, double b, double c, double &ans1, double &ans2 ){
28     double tmp = b * b - 4 * a * c;
29     if( dcmp(tmp) <= 0 ){
30         ans1 = ans2 = -1; return ;
31     }
32     tmp = sqrt(tmp);
33     ans1 = ( -b - tmp ) / 2 / a, ans2 = ( -b + tmp ) / 2 / a;
34 }
35 double x, y, z, xx, yy, zz;
36 int readint() {
37     char c;
38     bool f = 0;
39     while((c = getchar()) && !(c >= '0' && c <= '9') && c != '-');
40     int ret;
41     if(c == '-') ret = 0, f = 1;
42     else
43         ret = c - '0';
44     while((c = getchar()) && c >= '0' && c <= '9')
45         ret = ret * 10 + c - '0';
46     if(f) ret = -ret;
47     return ret;
48 }
49 int main(){
50     //freopen("tt.txt", "r", stdin);
51     int cas, kk = 1;
52     scanf("%d", &cas);
53     while(cas--){
54         int n, cnt = 0;
55         scanf("%d", &n);
56         scanf("%lf", &RR);
57         for(int i = 0; i < n; ++i){
58             x = readint();
59             y = readint();
60             z = readint();
61             xx = readint();
62             yy = readint();
63             zz = readint();
64             //printf("%lf %lf %lf
", x, y, z);
65             double a = xx * xx + yy * yy + zz * zz;
66             double b = 2 * x * xx + 2 * y * yy + 2 * z * zz;
67             double c = x * x + y * y + z * z - RR * RR;
68             double ans1, ans2;
69             calc(a, b, c, ans1, ans2);
70             if( dcmp(ans1 + 1) == 0 && dcmp(ans2 + 1) == 0 ) continue;
71             if( ans2 < 0 ) continue;
72             if( ans1 < 0 )
73                 ans1 = 0;
74             g[cnt].L = ans1, g[cnt++].R = ans2;
75         }
76         sort( g, g + cnt );
77         int ans = 0;
78         double pre = -1;
79         for(int i = 0; i < cnt; ++i){
80             if(g[i].L > pre)
81                 pre = g[i].R, ans++;
82         }
83         printf("Case %d: %d %d
", kk++, cnt, ans);
84     }
85     return 0;
86 }
View Code

FZU 2145 Rock-Paper-Scissors Game

概率题,并不会。

接下来三题好像都挺水的。

FZU 2146 Easy Game

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <cstring>
 7 #include <vector>
 8 #include <map>
 9 using namespace std;
10 #define N ( 100000 + 10 )
11 #define M ( 400000 + 10 ) 
12 #define LL long long
13 #define inf 0x3f3f3f3f
14 #define lson id << 1, l, m 
15 #define rson id << 1 | 1, m + 1, r 
16 #define mod 1000
17 
18 
19 char s[20000];
20 
21 int main () {
22     int T, cas = 1;
23     scanf("%d", &T );
24     while( T-- ) {
25         scanf("%s" , s );
26         int len = strlen( s );
27         printf("Case %d: ", cas ++ );
28         if( len % 2 ) puts("Odd");
29         else puts("Even");
30     }
31 }
View Code

FZU 2147 A-B Game

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 #define N 120
 8 #define M 200020
 9 #define LL long long
10 #define inf 0x3f3f3f3f
11 #define eps 1e-8
12 
13 int main(){
14     int  cas, kk = 1;
15     scanf("%d", &cas);
16     while( cas-- ){
17         LL B, A;
18         cin>>A>>B;
19         int ans = 0;
20         while( A > B ) {
21             if( A & 1 ) A = A - A / 2;
22             else A = A - A / 2 + 1;
23             ++ans;
24         }
25         printf("Case %d: ", kk++ );
26         printf("%d
", ans );
27     }
28     return 0;
29 }
View Code

FZU 2148 Moon Game

题意:给n(n<=30)个点,叫你求有多少组 4个点同时这四个点组成是图形是个凸包。

做法:暴力。n的4次方

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <queue>
  7 using namespace std;
  8 
  9 #define N 120
 10 #define M 200020
 11 #define LL long long
 12 #define inf 0x3f3f3f3f
 13 #define eps 1e-8
 14 /*
 15 double x[N], y[N];
 16 int n;
 17 double calc2(double tmp){
 18     double ret = 1 - (tmp+0.5)*(tmp+0.5);
 19     return sqrt(ret);
 20 }
 21 double calc1(double tmp){
 22     double ret = 1 - (tmp-0.5)*(tmp-0.5);
 23     return sqrt(ret);
 24 }
 25 void solve( int L, int R ){
 26     x[0] = 0.5, y[0] = 0;
 27     x[1] = -0.5, y[0] = 0;
 28     x[2] = 0, y[2] = sqrt(3.0) / 2;
 29     int cnt = 3;
 30     double len = -0.5 / (L + 1), tmp = len;
 31     for(int i = 0; i < L; ++i, tmp += len){
 32         double yy = calc1( tmp );
 33         x[cnt] = tmp, y[cnt++] = yy;
 34     }
 35     len = 0.5 / (R + 1), tmp = len;
 36     for(int i = 0; i < R; ++i, tmp += len){
 37         double yy = calc2( tmp );
 38         x[cnt] = tmp, y[cnt++] = yy;
 39     }
 40     for(int i = 0; i < cnt; ++i){
 41         printf( "%.6lf %.6lf
", x[i], y[i] );
 42     }
 43 }
 44 int main(){
 45     int cas, kk = 1;
 46     scanf("%d", &cas);
 47     while( cas-- ){
 48         scanf("%d", &n);
 49         if( n <= 3 ){
 50             puts( "No" ); continue;
 51         }
 52         puts( "Yes" );
 53         n -= 3;
 54         int L = n / 2, R = n - L;
 55         solve(L, R);
 56     }
 57     return 0;
 58 }
 59 */
 60 struct point{
 61     int x, y;
 62     point(int x = 0, int y = 0) : x(x), y(y) {}
 63     point operator + (const point &b) const {
 64         return point(x + b.x, y + b.y);
 65     }
 66     point operator - (const point &b) const {
 67         return point(x - b.x, y - b.y);
 68     }
 69     bool operator < (const point &b) const {
 70         return x - b.x < 0 || x - b.x == 0 && y - b.y < 0;
 71     }
 72     bool operator == (const point &b) const {
 73         return x - b.x == 0 && y - b.y == 0;
 74     }
 75 };
 76 int cross(point a, point b){
 77     return a.x * b.y - a.y * b.x;
 78 }
 79 int convex_hull(point *p, int n, point *ch){
 80     int m = 0;
 81     sort(p, p + n);
 82     for(int i = 0; i < n; ++i){
 83         while(m > 1 && cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--;
 84         ch[m++] = p[i];
 85     }
 86     int k = m;
 87     for(int i = n-2; i >= 0; --i){
 88         while(m > k && cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0 ) m--;
 89         ch[m++] = p[i];
 90     }
 91     if(n > 1) m--;
 92     return m;
 93 }
 94 point p[N], ch[N], pp[N];
 95 int main(){
 96     //freopen("tt.txt", "r", stdin );
 97     int cas, kk = 1;
 98     scanf("%d", &cas);
 99     while(cas--){
100         int n;
101         scanf("%d", &n);
102         for(int i = 0; i < n; ++i)
103             scanf("%d%d", &p[i].x, &p[i].y);
104         sort(p, p+n);
105         n = unique(p, p+n) - p;
106         int ans = 0;
107         for(int i = 0; i < n; ++i){
108             pp[0] = p[i];
109             for(int j = i+1; j < n; ++j){
110                 pp[1] = p[j];
111                 for(int k = j+1; k < n; ++k){
112                     pp[2] = p[k];
113                     for(int u = k+1; u < n; ++u){
114                         pp[3] = p[u];
115                         int all = convex_hull(pp, 4, ch);
116                         if(all == 4) ans++;
117                     }
118                 }
119             }
120         }
121         printf("Case %d: %d
", kk++, ans);
122     }
123     return 0;
124 }
View Code

FZU 2149 Reverse Game

小坤子的dp+矩阵加速被卡了,最后一分钟写出来,立刻过了样例,还以为绝杀了,结果TLE,应该卡常数了。

FZU 2150 Fire Game

题意:n*m的图,'.'表示空地,’#‘表示草堆,两个人任选两个草堆(可以选一样的)开始烧,问能不能把所有的草堆烧完,以及烧完的最短时间。

做法:枚举从哪两个起点开始烧,bfs就好。(应该是酱紫做,纬哥敲的)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 #define N 120
 8 #define M 200020
 9 #define LL long long
10 #define inf 0x3f3f3f3f
11 #define eps 1e-8
12 
13 char g[33][33];
14 
15 int ans;
16 int Qx[10000], Qy[10000];
17 int d[22][22];
18 int dx[] = { -1, 1, 0, 0 };
19 int dy[] = { 0, 0, -1, 1 };
20 int n, m;
21 void bfs ( int x1, int y1, int x2, int y2 ) {
22     int head = 0, tail = 0;
23     memset( d, 0x3f, sizeof( d ));
24     d[x1][y1] = d[x2][y2] = 0;
25     Qx[tail] = x1, Qy[tail++] =y1;
26     Qx[tail] = x2; Qy[tail++] = y2;
27     while( head < tail ) {
28         int nx = Qx[head], ny = Qy[head++];
29         for( int i = 0; i < 4; ++i ) {
30             int xx = dx[i] + nx, yy = dy[i] + ny;
31             if( xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
32             if( d[xx][yy] != inf ) continue;
33             if( g[xx][yy] == '.' ) continue;
34             d[xx][yy] = d[nx][ny] + 1;
35             Qx[tail] = xx, Qy[tail++] = yy;
36         }
37     }
38 }
39 
40 void check () {
41     int tmp = 0;
42     for( int i = 0; i < n; ++i ) {
43         for( int j = 0; j < m; ++j ) {
44             if( g[i][j] == '.' ) continue;
45             tmp = max( d[i][j], tmp );
46         }
47     }
48     ans = min (ans, tmp );
49 }
50 
51 int main(){
52     int T, cas = 1;
53     //freopen("tt.txt", "r", stdin );
54     scanf("%d", &T );
55 
56     while( T-- ){
57         ans = inf;
58         scanf("%d%d", &n, &m );
59         for( int i = 0; i < n; ++i )
60             scanf("%s", g[i] );
61 
62         for( int i = 0; i < n; ++i ) {
63             for( int j = 0; j < m; ++j ) {
64                 if( g[i][j] == '.' ) continue;
65                 for( int k = 0; k < n; ++k ) {
66                     for( int z = 0; z < m; ++z ) {
67                         if( g[k][z] == '.' ) continue;
68                         bfs( i, j, k, z );
69                         check();
70                     }
71                 }
72             }
73         }
74         printf("Case %d: ", cas ++ );
75         if( ans == inf ) puts("-1" );
76         else printf("%d
", ans );
77     }
78     return 0;
79 }
View Code

FZU 2151 OOXX Game

太水了,不贴代码了

原文地址:https://www.cnblogs.com/LJ-blog/p/4421160.html