15.3.17周练
连接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=72057#overview
密码acmore
A:最小费用流
结题报告:http://www.cnblogs.com/gj-Acit/p/4374951.html
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 10010; 36 const int MAXM = 20010; 37 const double eps = 1e-4; 38 39 40 const int dx[4] = {0, 1, 0, -1}; 41 const int dy[4] = {1, 0, -1, 0}; 42 int T, N, M, K, B, ans = 0; 43 44 /*******************************************************************/ 45 struct Edge { 46 int to, cap, flow, cost, next; 47 Edge(){} 48 Edge(int _n, int _v, int _c, int _f, int _cost){ 49 next = _n; to = _v; cap = _c; 50 flow = _f; cost = _cost; 51 } 52 }; 53 54 struct MCMF 55 { 56 int n, m, src, des; 57 int head[MAXN], tot; 58 Edge edges[MAXM]; 59 int inq[MAXN]; 60 int d[MAXN]; 61 int p[MAXN]; 62 int a[MAXN]; 63 64 void init(int n) { 65 this->tot = 0; 66 this->n = n; 67 mem1(head); 68 } 69 70 void add_edge(int from, int to, int cap, int cost) { 71 edges[tot] = Edge(head[from], to, cap, 0, cost); 72 head[from] = tot ++; 73 edges[tot] = Edge(head[to], from, 0, 0, -cost); 74 head[to] = tot ++; 75 } 76 77 bool bellman_ford(int s, int t, int& flow) { 78 for(int i = 0; i < n; i ++) { 79 d[i] = INF; 80 inq[i] = 0; 81 } 82 d[s] = 0; inq[s] = 1; 83 p[s] = 0; a[s] = INF; 84 85 queue<int>Q; 86 Q.push(s); 87 while(!Q.empty()) { 88 int u = Q.front(); Q.pop(); 89 inq[u] = false; 90 for(int i = head[u]; i != -1; i = edges[i].next) { 91 int v = edges[i].to; 92 if(edges[i].cap > edges[i].flow && d[v] > d[u] + edges[i].cost) { 93 d[v] = d[u] + edges[i].cost; 94 p[v] = i; 95 a[v] = min(a[u], edges[i].cap - edges[i].flow); 96 if(!inq[v]) { 97 Q.push(v); 98 inq[v] = 1; 99 } 100 } 101 } 102 } 103 if(d[t] >= 0) return false; 104 105 flow += a[t]; 106 ans += d[t] * a[t]; 107 108 int u = t; 109 while(u != s) { 110 edges[p[u]].flow += a[t]; 111 edges[p[u]^1].flow -= a[t]; 112 u = edges[p[u]^1].to; 113 } 114 return true; 115 } 116 117 int min_cost(int s, int t) { 118 int flow = 0; 119 while(bellman_ford(s, t, flow)); 120 return ans; 121 } 122 123 }; 124 /***************************************************************/ 125 126 int idx(int i, int j) { 127 return (i - 1) * M + j; 128 } 129 130 int ok(int i, int j) { 131 return (i >= 1 && i <= N && j >= 1 && j <= M); 132 } 133 134 135 MCMF mcmf; 136 137 int main() 138 { 139 //FIN; 140 cin >> T; 141 rep (t, 1, T) { 142 scanf("%d %d %d", &N, &M, &K); 143 mcmf.init(N * M + 2); 144 mcmf.src = 0; mcmf.des = N * M + 1; ans = 0; 145 rep (i, 1, N) rep (j, 1, M) { 146 scanf("%d", &B); 147 ans += B * B; 148 if(i % 2 == j % 2) rep (k, 1, K) { 149 mcmf.add_edge(mcmf.src, idx(i, j), 1, 2 * k - 1 - 2 * B); 150 rep (k, 0, 3) if(ok(i + dx[k], j + dy[k])) { 151 mcmf.add_edge(idx(i, j), idx(i + dx[k], j + dy[k]), INF, 0); 152 } 153 } 154 else rep (k, 1, K) { 155 mcmf.add_edge(idx(i, j), mcmf.des, 1, 2 * k - 1 - 2 * B); 156 } 157 } 158 printf("Case %d: %d\n", t, mcmf.min_cost(mcmf.src, mcmf.des)); 159 } 160 return 0; 161 }
B:贪心
算出每只文字穿过球体的时间段,然后就是求所有时间段(线段)的最小覆盖次数,贪心
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1100; 36 const int MAXM = 2000010; 37 const double eps = 1e-4; 38 39 struct Point { 40 double x, y, z; 41 Point(){} 42 Point(double _x, double _y, double _z):x(_x), y(_y), z(_z){} 43 }O(0, 0, 0); 44 struct Line{ 45 double a, b; 46 bool operator < (const Line& A) const { 47 return b != A.b ? b < A.b : a < A.a; 48 } 49 }l[110000]; 50 51 int n, T, cntL = 0, A, B; 52 double R; 53 54 double dis(Point a, Point b) { 55 return (double)sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) + (a.z - b.z)*(a.z - b.z)); 56 } 57 58 int convert(Point p, Point v) 59 { 60 double a = v.x*v.x + v.y*v.y + v.z*v.z; 61 double b = 2.0 * (p.x*v.x + p.y*v.y + p.z*v.z); 62 double c = p.x*p.x + p.y*p.y + p.z*p.z - R * R; 63 double del = b * b - 4.0 * a * c; 64 if(del < 0) return 0; 65 double x1 = (-b - sqrt(del)) / (2 * a), x2 = (-b + sqrt(del)) / (2 * a); 66 if(x2 < 0) return 0; 67 l[cntL].a = max(x1, 0.0); 68 l[cntL++].b = x2; 69 return 1; 70 } 71 72 int calcAnsB() 73 { 74 sort(l, l + cntL); 75 double lasR = -1e10; 76 int ret = 0; 77 for(int i = 0; i < cntL; i ++) { 78 if(l[i].a - lasR > eps) { 79 ret ++; 80 lasR = l[i].b; 81 } 82 } 83 return ret; 84 } 85 86 int main() 87 { 88 //FIN; 89 Point p, v; 90 cin>>T; 91 rep (t, 1, T) { 92 scanf("%d %lf", &n, &R); 93 A = 0; B = 0; cntL = 0; 94 int x,y,z,a,b,c; 95 rep (i, 0, n - 1) { 96 scanf("%d %d %d %d %d %d", &x, &y, &z, &a, &b, &c); 97 l[i].a = l[i].b = -1; 98 p.x = x; p.y = y; p.z = z; 99 v.x = a; v.y = b; v.z = c; 100 A += convert(p, v); 101 } 102 103 B = calcAnsB(); 104 printf("Case %d: %d %d\n", t, A, B); 105 } 106 return 0; 107 }
C:Easy Game,Easy
1 import java.util.Scanner; 2 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int t = cin.nextInt(); 8 for(int i = 1; i <= t; i ++) { 9 String s = cin.next(); 10 System.out.print("Case " + i + ": "); 11 if(s.length() % 2 == 1)System.out.println("Odd"); 12 else System.out.println("Even"); 13 } 14 }
D:贪心,每次取最接近x/2的数
1 import java.math.BigInteger; 2 import java.util.Scanner; 3 4 5 public class Main { 6 public static void main(String[] args) { 7 Scanner cin = new Scanner(System.in); 8 BigInteger TWO = new BigInteger("2"); 9 int t = cin.nextInt(); 10 for(int i = 1; i <= t; i ++) { 11 BigInteger A = cin.nextBigInteger(); 12 BigInteger B = cin.nextBigInteger(); 13 int ans = 0; 14 while(A.compareTo(B) > 0) { 15 A = A.subtract(A.mod(A.divide(TWO).add(BigInteger.ONE))); 16 ans ++; 17 } 18 System.out.println("Case " + i + ": " + ans); 19 } 20 } 21 }
E:求凸四边形个数,暴力枚举,若两条线断相交则这四个点可以组成凸四边形
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define eps 1e-12 16 #define MAXN 55 17 #define INF 1e30 18 #define mem0(a) memset(a,0, sizeof(a)) 19 #define mem1(a) memset(a,-1,sizeof(a)) 20 double MAX(double a, double b) {return a > b ? a : b;} 21 double MIn(double a, double b) {return a < b ? a : b;} 22 typedef __int64 LL; 23 /****************************************计算几何头文件**************************************************/ 24 struct Point{ 25 LL x,y; 26 Point(LL x=0, LL y=0):x(x),y(y){} 27 }; 28 29 Point operator + (Point A, Point B) {return Point(A.x+B.x, A.y+B.y);} 30 31 Point operator - (Point A, Point B) {return Point(A.x-B.x, A.y-B.y);} 32 33 LL cross(Point A, Point B) {return A.x*B.y - A.y*B.x;} 34 35 bool crossed(Point a, Point b, Point c, Point d)//线段ab和cd是否相交 36 { 37 if(cross(a-c, d-c)*cross(b-c, d-c)<0 38 && cross(c-a, b-a)*cross(d-a, b-a)<0) 39 { 40 return true; 41 } 42 return false; 43 } 44 45 /****************************************************************************************************/ 46 47 int T, N; 48 Point p[100]; 49 50 int is(int a, int b, int c, int d) 51 { 52 if(crossed(p[a], p[b], p[c], p[d]) 53 ||crossed(p[a], p[c], p[b], p[d]) 54 ||crossed(p[a], p[d], p[b], p[c])) { 55 return 1; 56 } 57 return 0; 58 } 59 60 int main() 61 { 62 cin >> T; 63 for(int t = 1; t <= T; t ++) { 64 cin >> N; 65 for(int i = 0; i < N; i ++) { 66 scanf("%I64d %I64d", &p[i].x, &p[i].y); 67 } 68 LL ans = 0; 69 for(int i = 0; i < N; i ++) { 70 for(int j = i + 1; j < N; j ++) { 71 for(int k = j + 1; k < N; k ++) { 72 for(int l = k + 1; l < N; l ++) { 73 if(is(i, j, k, l)) ans ++; 74 } 75 } 76 } 77 } 78 cout <<"Case " << t << ": "; 79 cout << ans << endl; 80 } 81 return 0; 82 }
F:不会
G:暴力枚举
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FOPENIN(IN) freopen(IN, "r", stdin) 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1100; 36 const int MAXM = 2000010; 37 const double eps = 1e-10; 38 39 const int dx[4] = {-1, 0, 1, 0}; 40 const int dy[4] = {0, -1, 0, 1}; 41 42 int T, M, N; 43 int vis[20][20]; 44 char ma[20][20]; 45 46 struct Point { 47 int x, y; 48 Point(){} 49 Point(int _x, int _y){ 50 x = _x; y = _y; 51 } 52 }p[110]; 53 int tot; 54 55 void dfs(int x, int y) { 56 if(x < 0 || x >= M || y < 0 || y >= N || vis[x][y] || ma[x][y]=='.') return ; 57 vis[x][y] = 1; 58 for(int i = 0; i < 4; i ++) { 59 dfs(x + dx[i], y + dy[i]); 60 } 61 } 62 63 int bfs(Point a, Point b) 64 { 65 mem1(vis); 66 queue<Point>q; 67 q.push(a); q.push(b); 68 vis[a.x][a.y] = vis[b.x][b.y] = 0; 69 int ret = 0, cnt = 2; 70 while(!q.empty()) { 71 Point fr = q.front(); q.pop(); 72 ret = vis[fr.x][fr.y]; 73 rep (d, 0, 3) { 74 int x = fr.x + dx[d], y = fr.y + dy[d]; 75 if(x >= 0 && x < M && y >= 0 && y < N && vis[x][y] == -1 && ma[x][y]=='#') { 76 q.push(Point(x, y)); 77 vis[x][y] = vis[fr.x][fr.y] + 1; 78 cnt ++; 79 } 80 } 81 } 82 if(cnt != tot) return INF; 83 return ret; 84 } 85 86 int main() 87 { 88 cin>>T; 89 for(int t = 1; t <= T; t ++) { 90 tot = 0; 91 printf("Case %d: ", t); 92 scanf("%d %d%*c", &M, &N); 93 rep (i, 0, M - 1) { 94 scanf("%s", ma[i]); 95 rep (j, 0, N - 1) { 96 if(ma[i][j] == '#') p[tot].x = i, p[tot++].y = j; 97 } 98 } 99 if(tot <= 2) { 100 cout<<0<<endl; 101 continue; 102 } 103 104 mem0(vis); 105 int num = 0; 106 rep (i, 0, M - 1) rep (j, 0, N - 1) if(!vis[i][j] && ma[i][j] == '#') { 107 dfs(i, j); 108 num ++; 109 } 110 if(num == 0 || num > 2) { 111 cout<<-1<<endl; 112 continue; 113 } 114 115 int ans = INF; 116 rep (i, 0, tot - 1) rep (j, i + 1, tot - 1) { 117 ans = min(ans, bfs(p[i], p[j])); 118 } 119 printf("%d\n", ans == INF ? -1 : ans); 120 } 121 return 0; 122 }