机器翻译
题解:模拟
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAXN = 1000; 5 6 int n, m, cj, now, MinV, MinId, Pri, a[MAXN+10], in[MAXN+10]; 7 8 int main(){ 9 memset(in, -1, sizeof(in)); 10 scanf("%d %d", &n, &m), now = Pri = 0; 11 for (int i=0; i<m; i++){ 12 scanf("%d", &cj); 13 if (~in[cj]) continue; 14 Pri ++; 15 if (now+1<=n) now ++, in[cj] = i; 16 else { 17 MinV = 0x3f3f3f3f; 18 for (int j=0; j<=MAXN; j++) 19 if (in[j]<MinV && in[j]!=-1) MinV = in[j], MinId = j; 20 in[MinId] = -1, in[cj] = i; 21 } 22 } 23 printf("%d ", Pri); 24 }
乌龟棋
题解:dp
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAXN = 350+2; 5 const int MAXE = 40+2; 6 7 int n, m, cj, a[MAXN], b[6], dp[MAXE][MAXE][MAXE][MAXE]; 8 9 int main(){ 10 memset(dp, 0, sizeof(dp)); 11 12 scanf("%d %d", &n, &m); 13 for (register int i=0; i<n; i++) 14 scanf("%d", &a[i]); 15 for (register int i=0; i<m; i++) 16 scanf("%d", &cj), b[cj] ++; 17 18 dp[0][0][0][0] = a[0]; 19 for (register int A=0; A<=b[1]; A++) 20 for (register int B=0; B<=b[2]; B++) 21 for (register int C=0; C<=b[3]; C++) 22 for (register int D=0; D<=b[4]; D++){ 23 cj = A+B+B+C+C+C+D+D+D+D; 24 if (A && dp[A-1][B][C][D]+a[cj]>dp[A][B][C][D]) dp[A][B][C][D] = dp[A-1][B][C][D]+a[cj]; 25 if (B && dp[A][B-1][C][D]+a[cj]>dp[A][B][C][D]) dp[A][B][C][D] = dp[A][B-1][C][D]+a[cj]; 26 if (C && dp[A][B][C-1][D]+a[cj]>dp[A][B][C][D]) dp[A][B][C][D] = dp[A][B][C-1][D]+a[cj]; 27 if (D && dp[A][B][C][D-1]+a[cj]>dp[A][B][C][D]) dp[A][B][C][D] = dp[A][B][C][D-1]+a[cj]; 28 } 29 printf("%d ", dp[b[1]][b[2]][b[3]][b[4]]); 30 }
关押罪犯
题解:并查集。既然只有两个监狱,那么如果a和b没有在一个监狱,b和c没有在一个监狱,那么a和c一定在一个监狱
把怒气值从大到小拍个序,依次处理
并查集[1, n]表示和自己一起的,[n+1, 2n]表示不和自己一起的
1 #include <cstdio> 2 #include <algorithm> 3 using std::sort; 4 5 const int MAXN = 20000+10; 6 const int MAXM = 100000+10; 7 8 int n, m, f[MAXN*2]; 9 10 struct Relation{ 11 int a, b, c; 12 13 friend bool operator < (const Relation& A, const Relation& B){ 14 return A.c>B.c; 15 } 16 }r[MAXM]; 17 18 inline int Find(int x){ 19 return f[x]==x ? x : f[x] = Find(f[x]); 20 } 21 22 inline int Solve(){ 23 sort(r, r+m); 24 int a, b; 25 for (int i=0; i<m; i++){ 26 a = Find(r[i].a), b = Find(r[i].b); 27 if (a==b) return r[i].c; 28 else f[a] = Find(r[i].b+n), f[b] = Find(r[i].a+n); 29 } 30 return 0; 31 } 32 33 int main(){ 34 scanf("%d %d", &n, &m); 35 for (int i=1; i<=2*n; i++) 36 f[i] = i; 37 for (int i=0; i<m; i++) 38 scanf("%d %d %d", &r[i].a, &r[i].b, &r[i].c); 39 40 printf("%d ", Solve()); 41 }
引水入城
题解:看懂题是关键...
多么痛的领悟:windows下只能bfs,linux下就怎么搞都可以了TAT
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAXN = 500+10; 5 const int addX[] = {-1, 1, 0, 0}; 6 const int addY[] = {0, 0, -1, 1}; 7 8 int n, m, X, Y, Need, Cant, anna[MAXN][MAXN]; 9 bool vis[MAXN][MAXN]; 10 11 struct Region{ 12 int l, r; 13 }rg[MAXN]; 14 15 inline int findLeft(){ 16 for (int i=1; i<=m; i++) 17 if (vis[n][i]) return i; 18 return 0; 19 } 20 21 inline int findRight(){ 22 for (int i=m; i>=1; i--) 23 if (vis[n][i]) return i; 24 return 0; 25 } 26 27 inline void DFS(int x, int y){ 28 if (x<1 || x>n || y<1 || y>m) return; 29 vis[x][y] = true; 30 31 for (int i=0; i<4; i++){ 32 X = x+addX[i], Y = y+addY[i]; 33 if (1<=X && X<=n && 1<=Y && Y<=m && anna[X][Y]<anna[x][y] && !vis[X][Y]) 34 DFS(X, Y); 35 } 36 } 37 38 inline bool legal(){ 39 memset(vis, false, sizeof(vis)); 40 41 for (int i=1; i<=m; i++) 42 DFS(1, i); 43 44 for (int i=1; i<=m; i++) 45 if (not vis[n][i]) ++ Cant; 46 47 return !Cant; 48 } 49 50 inline int segmentCover(){ 51 for (int i=1; i<=m; i++){ 52 memset(vis, false, sizeof(vis)); 53 DFS(1, i); 54 rg[i].l = findLeft(), rg[i].r = findRight(); 55 } 56 57 int i = 1, j, k = 0; 58 while (i<=m){ 59 for (j=1; j<=m; j++) 60 if (rg[j].l<=i && rg[j].r>k) k = rg[j].r; 61 i = k+1, ++ Need; 62 } 63 64 return Need; 65 } 66 67 int main(){ 68 memset(anna, 0x3f, sizeof(anna)); 69 70 scanf("%d %d", &n, &m), Cant = Need = 0; 71 for (int i=1; i<=n; i++) 72 for (int j=1; j<=m; j++) 73 scanf("%d", &anna[i][j]); 74 75 if (legal()) printf("1 %d", segmentCover()); 76 else printf("0 %d", Cant); 77 }