Training Contest 1
好像是福建省赛。
题意:叫你找满足条件的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\n", 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 }
题意:给出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 }
题意:给出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\n", 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 }
费用流。小坤子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\n", ++kk, sum + go.go(s, t)); 153 154 } 155 return 0; 156 }
题意:空间内有若干只蚊子,蚊子会朝着一个方向不停地飞,一个人站在原点拿着一把枪,他可以在任何时间开枪,每次他开枪,周围半径为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\n", 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\n", kk++, cnt, ans); 84 } 85 return 0; 86 }
FZU 2145 Rock-Paper-Scissors 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 }
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\n", ans ); 27 } 28 return 0; 29 }
题意:给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\n", 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\n", kk++, ans); 122 } 123 return 0; 124 }
小坤子的dp+矩阵加速被卡了,最后一分钟写出来,立刻过了样例,还以为绝杀了,结果TLE,应该卡常数了。
题意: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\n", ans ); 77 } 78 return 0; 79 }
太水了,不贴代码了