每日打卡 2017.03.12 POJ题目分类 初级-一、基本算法

    xiaoxiao2021-03-25  58

    POJ 1753

    Tip1:枚举法,C(0,16)+C(1,16)+C(2,16)+...+C(16,16)=2^16,且最后一次不需要,根据题目意思,后一半也不需要。这题最关键的就是要注意到选2次以上没有意义,所以要么选,要么不选,这样就可以穷举了。

    Tip2:这题跑了120ms,如果不用双参数的dfs穷举上一个排列数,而是单参数穷举,那GG,能穷举组合数就不要穷举全排列

    #include<iostream> #include<cstring> using namespace std; int a[4][4]; int b[4][4]; int m[16]; const int dl[] = {-1, 0, 1, 0, 0}; const int dr[] = {0, -1, 0, 1, 0}; bool vis[16]; string str; bool ok() { for(int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { if((b[i][j] % 2) != (b[0][0] % 2)) return false; } } return true; } bool dfs(int cur, int tot, int p) { if(cur == tot) { memcpy(b, a, sizeof(b)); for(int i = 0; i < 16; i++) { if(vis[i]) { int l = i / 4; int r = i % 4; for(int i = 0; i < 5; i++) { if(l+dl[i] >= 0 && l+dl[i] < 4 && r + dr[i] >= 0 && r + dr[i] < 4)b[l+dl[i]][r+dr[i]]++; } } } if(ok())return true; } else { for(int i = p; i < 16; i++) { if(!vis[i]) { vis[i] = true; if(dfs(cur + 1, tot, i + 1)) return true; vis[i] = false; } } } return false; } int main(){ freopen("input.txt", "r", stdin); for(int i = 0; i < 4; i++) { cin >> str; for(int j = 0; j < 4; j++) { if(str[j] == 'b') a[i][j] = 1; } } memcpy(b, a, sizeof(b)); int flag = 0; if(ok()) { cout << 0 << endl; flag = 1; } else for(int i = 1; i < 9; i++) { if(dfs(0, i, 0)) { flag = 1; cout << i << endl; break; } } if(flag == 0) cout << "Impossible" << endl; return 0; }

    POJ 2965

    Tip1:一样的思路,但是!刚刚穷举0-8,现在穷举1-16,因此循环必须是i<17!这里因为i<16一直在WA!c(0,16)到c(0,16)一共是17个数字!组合数穷举格式见下

    #include<iostream> #include<cstring> using namespace std; int a[4][4]; int b[4][4]; int m[16]; bool vis[16]; string str; bool ok() { for(int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { if(b[i][j] % 2 != 0) return false; } } return true; } bool dfs(int cur, int tot, int p) { if(cur == tot) { memcpy(b, a, sizeof(b)); for(int i = 0; i < 16; i++) { if(vis[i]) { int l = i / 4; int r = i % 4; b[l][r]++; for(int i = 0; i < 4; i++) { b[l][i]++; b[i][r]++; } } } if(ok())return true; } else { for(int i = p; i < 16; i++) { if(!vis[i]) { vis[i] = true; if(dfs(cur + 1, tot, i + 1)) return true; vis[i] = false; } } } return false; } int main() { freopen("input.txt", "r", stdin); for(int i = 0; i < 4; i++) { cin >> str; for(int j = 0; j < 4; j++) { if(str[j] == '+') a[i][j] = 1; } } for(int i = 1; i < 17; i++) { if(dfs(0, i, 0)) { cout << i << endl; for(int j = 0; j < 16; j++) { if(vis[j]) { int l = (j / 4) + 1; int r = (j % 4) + 1; cout << l << " " << r << endl; } } break; } } return 0; }

    POJ 1328

    Tip1:问题看清楚!再转化为熟悉的问题!不能想当然的贪心!

    Tip2:粉皮P233

    区间选点问题:n个闭区间,选最少的点,使得每个区间上都有一个点

    按区间的右端排列,然后按次序判断其左端点即可。

    不能想当然的贪心!必须要比划一下证明!

    #include<iostream> #include<algorithm> #include<cmath> using namespace std; int n, d; const int MAXN = 1000 + 5; struct Node { int x, y; double l, r; bool init() { cin >> x >> y; if(y > d)return true; l = x - sqrt(d*d - y*y); r = x + sqrt(d*d - y*y); return false; } }node[MAXN]; bool operator < (const Node& a, const Node& b) { if(b.r != a.r)return a.r < b.r; else return a.l < b.l; } int main() { freopen("input.txt", "r", stdin); int kase = 0, ans; while(cin >> n >> d) { if(n == 0 && d == 0)break; int ans = 1; for(int i = 0; i < n; i++) { if(node[i].init()) ans = -1; } if(ans != -1) { sort(node, node + n); double p = node[0].r; for(int i = 1; i < n; i++) { if(node[i].l > p) { p = node[i].r; ans++; } } } cout << "Case " << ++kase << ": " << ans << endl; } return 0; }

    POJ 2109

    Tip1:个别oj不加<stdio>就使用printf会报错(devcpp不会)

    Tip2:所谓贪心不是一种特定的算法,而是怎样巧妙的方法刚巧能得到我们要的答案。不能遇到指数就想到对数,还应该想到1/n次方

    Tip3:printf输出double用%f不用%lf!切记!

    Tip4:printf输出double如果不要小数点,只要%.0f即可

    Tip5:double的有效数字是15-16位,大小范围在正负十的308次方之间!不要看到超过long的就想string,也要想到double!

    Tip6:有效数字意思是保证十进制下的前15位有效数字正确,而题目只到前9位,所以误差可以忽略

    #include<iostream> #include<cmath> #include<cstdio> using namespace std; int main() { freopen("input.txt", "r", stdin); double n, p; while(cin >> n >> p) { printf("%.0f\n", pow(p, 1/n)); } return 0; } java 二分高精度:

    (此题数据有问题,这里关于ok的判断根本不必加)

    import java.math.BigInteger; import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); BigInteger p = sc.nextBigInteger(); int l = 1, r = 1000000001; boolean ok = false; while(l < r) { int mid = (l + r)/2; BigInteger q = BigInteger.valueOf(mid).pow(n); int zz = q.compareTo(p); if(zz == 0) { ok = true; System.out.println(mid); break; } else if(zz == -1) { l = mid + 1; } else { r = mid; } } if(!ok) { while(BigInteger.valueOf(l).pow(n).compareTo(p)==-1)l++; System.out.println(l-1); } } } }

    POJ 2586

    这题唯一难点是英文

    回溯剪枝:219ms

    //回溯剪枝 #include<iostream> using namespace std; int s, d; int ans; int a[12]; void dfs(int cur) { if(cur == 12) { int sum = a[0] + a[1] + a[2] + a[3] + a[4]; if(sum >= 0)return; for(int i = 5; i < 12; i++) { sum += a[i]; sum -= a[i-5]; if(sum >= 0)return; } sum = 0; for(int i = 0; i < 12; i++) sum += a[i]; if(sum > ans) ans = sum; } else { a[cur] = s; dfs(cur + 1); a[cur] = -d; dfs(cur + 1); } } int main() { freopen("input.txt", "r", stdin); while(cin >> s >> d) { ans = -1; dfs(0); if(ans == -1) cout << "Deficit" << endl; else cout << ans << endl; } return 0; } 剪得更夸张一点:129ms

    #include<iostream> using namespace std; int s, d; int ans; int a[12]; void dfs(int cur) { if(cur == 12) { int sum = 0; for(int i = 0; i < 12; i++) sum += a[i]; if(sum > ans) ans = sum; } else { a[cur] = s; if(cur >= 4) { int sum = 0; for(int i = 0; i < 5; i++) { sum += a[cur - i]; } if(sum < 0) dfs(cur + 1); } else { dfs(cur + 1); } a[cur] = -d; if(cur >= 4) { int sum = 0; for(int i = 0; i < 5; i++) { sum += a[cur - i]; } if(sum < 0) dfs(cur + 1); } else { dfs(cur + 1); } } } int main() { //freopen("input.txt", "r", stdin); while(cin >> s >> d) { ans = -1; dfs(0); if(ans == -1) cout << "Deficit" << endl; else cout << ans << endl; } return 0; }

    POJ 3295

    回溯穷举

    Tip1:当算法没有问题时,检查细节,某些变量逻辑上的错误,比如我这里return true的判断一开始是'b',其实不然,应该是任何为假的字符,因为多层嵌套导致我没有一下子转过弯来

    从左往右:

    #include<iostream> #include<cstdio> #include<cstring> #include<map> #include<vector> using namespace std; char str[105]; map<char, int> M; bool zz[7]; bool ac(char t) { if(t >= 'A' && t <= 'Z') return true; else return false; } bool dfs(int cur) { if(cur == 5) { vector<char> v; int len = strlen(str); bool ok = false; for(int i = 0; i < len; i++) { v.push_back(str[i]); while(!v.empty()) { if(v.size() > 1) { if(v[v.size() - 2] == 'N' && !ac(v[v.size() - 1])) { char tmp = v[v.size() - 1]; v.pop_back(); v.pop_back(); if(zz[M[tmp]]) v.push_back('b'); else v.push_back('a'); continue; } } if(v.size() > 2) { char c1 = v[v.size() - 3]; char c2 = v[v.size() - 2]; char c3 = v[v.size() - 1]; if(ac(c1) && !ac(c2) && !ac(c3)) { v.pop_back(); v.pop_back(); v.pop_back(); if(c1 == 'K') { if(zz[M[c2]] && zz[M[c3]]) v.push_back('a'); else v.push_back('b'); } if(c1 == 'A') { if(!zz[M[c2]] && !zz[M[c3]]) v.push_back('b'); else v.push_back('a'); } if(c1 == 'C') { if(zz[M[c2]] && !zz[M[c3]]) v.push_back('b'); else v.push_back('a'); } if(c1 == 'E') { if(zz[M[c2]] == zz[M[c3]]) v.push_back('a'); else v.push_back('b'); } continue; } } break; } } if(!zz[M[v[0]]]) return true; } else { zz[cur] = false; if(dfs(cur+1))return true; zz[cur] = true; if(dfs(cur+1))return true; } return false; } int main() { //freopen("input.txt", "r", stdin); M['p'] = 0; M['q'] = 1; M['r'] = 2; M['s'] = 3; M['t'] = 4; M['a'] = 5; M['b'] = 6; zz[5] = true; zz[6] = false; while(scanf("%s", str) != EOF && str[0] != '0') { if(dfs(0)) printf("not\n"); else printf("tautology\n"); } return 0; } 从右往左:

    #include<iostream> #include<cstdio> #include<cstring> #include<map> #include<stack> using namespace std; char str[105]; map<char, int> M; bool zz[7]; bool ac(char t) { if(t >= 'A' && t <= 'Z') return true; else return false; } bool dfs(int cur) { if(cur == 5) { stack<char> v; int len = strlen(str); bool ok = false; for(int i = 0; i < len; i++) { v.push(str[len-1-i]); if(ac(v.top())) { if(v.top() == 'N') { v.pop(); char tmp = v.top(); v.pop(); if(zz[M[tmp]]) v.push('b'); else v.push('a'); continue; } char c1 = v.top(); v.pop(); char c2 = v.top(); v.pop(); char c3 = v.top(); v.pop(); if(c1 == 'K') { if(zz[M[c2]] && zz[M[c3]]) v.push('a'); else v.push('b'); } if(c1 == 'A') { if(!zz[M[c2]] && !zz[M[c3]]) v.push('b'); else v.push('a'); } if(c1 == 'C') { if(zz[M[c2]] && !zz[M[c3]]) v.push('b'); else v.push('a'); } if(c1 == 'E') { if(!zz[M[c2]] && !zz[M[c3]]) v.push('a'); else if(zz[M[c2]] && zz[M[c3]]) v.push('a'); else v.push('b'); } } } if(!zz[M[v.top()]]) return true; } else { zz[cur] = false; if(dfs(cur+1))return true; zz[cur] = true; if(dfs(cur+1))return true; } return false; } int main() { freopen("input.txt", "r", stdin); M['p'] = 0; M['q'] = 1; M['r'] = 2; M['s'] = 3; M['t'] = 4; M['a'] = 5; M['b'] = 6; zz[5] = true; zz[6] = false; while(scanf("%s", str) != EOF && str[0] != '0') { if(dfs(0)) printf("not\n"); else printf("tautology\n"); } return 0; }

    POJ 1068

    直接模拟

    #include<cstdio> #include<iostream> #include<cstring> #include<vector> #define sf(a) scanf("%d", &a) using namespace std; int T; int n; int a[22]; vector<int> v; int main() { freopen("input.txt", "r", stdin); sf(T); while(T--) { v.clear(); sf(n); for(int i = 0; i < n; i++) sf(a[i]); int last = 0; for(int i = 0; i < n; i++) { int tmp = a[i]-last; last = a[i]; for(int j = 0; j < tmp; j++) v.push_back(0); v.push_back(1); } bool flag = true; int tot = 0; for(int i = 0; i < v.size(); i++) { if(v[i] == 1) { int pos = i - 1; int ans = 1; while(v[pos] != 0) { if(v[pos] == 2) ans++; pos--; } v[pos] = 2; if(flag) flag = false; else printf(" "); printf("%d", ans); } } printf("\n"); } return 0; } POJ 2632

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> #define sf(a) scanf("%d", &a) #define sf2(a, b) scanf("%d%d", &a, &b) #define sfs(a) scanf("%s", a) using namespace std; const int MAXN = 100 + 5; int kase, a, b, n, m; char str[2]; int rob[MAXN]; int ins[MAXN]; int rep[MAXN]; int ra[MAXN]; int rb[MAXN]; int rt[MAXN]; const int dx[] = {0, 1, 0, -1}; const int dy[] = {1, 0, -1, 0}; struct Node { int x, y; Node(int _x, int _y): x(_x), y(_y){} }; bool operator < (const Node& a,const Node& b) { if(a.x == b.x) return a.y < b.y; else return a.x < b.x; } set<Node> S; int main() { freopen("input.txt", "r", stdin); sf(kase); while(kase--) { S.clear(); int flag = -1; sf2(a, b); sf2(n, m); for(int i = 0; i < n; i++) { sf(ra[i]); sf(rb[i]); S.insert(Node(ra[i], rb[i])); sfs(str); switch(str[0]) { case 'N':rt[i] = 0;break; case 'E':rt[i] = 1;break; case 'S':rt[i] = 2;break; case 'W':rt[i] = 3;break; } } for(int i = 0; i < m; i++) { sf(rob[i]);rob[i]--; sfs(str); sf(rep[i]); switch(str[0]) { case 'F':ins[i] = 0;break; case 'L':ins[i] = 1;break; case 'R':ins[i] = 2;break; } } // for(int i = 0; i < m; i++) cout << rob[i] << endl; for(int i = 0; i < m; i++) { if(ins[i] == 0) { int x = ra[rob[i]], y = rb[rob[i]]; S.erase(S.find(Node(x, y))); while(rep[i]--) { x += dx[rt[rob[i]]]; y += dy[rt[rob[i]]]; if(x < 1 || x > a || y < 1 || y > b) { flag = -2; printf("Robot %d crashes into the wall\n", rob[i] + 1); break; } if(S.count(Node(x, y)) == 1) { for(int j = 0; j < n; j++) { if(ra[j] == x && rb[j] == y) { flag = j; break; } } printf("Robot %d crashes into robot %d\n", rob[i] + 1, flag + 1); break; } } if(flag != -1)break; ra[rob[i]] = x; rb[rob[i]] = y; S.insert(Node(x, y)); } else { rep[i] %= 4; while(rep[i]--) { rt[rob[i]]+=(ins[i] == 2)?1:3; rt[rob[i]]%=4; } } } if(flag == -1) printf("OK\n"); } return 0; } POJ 1573

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> #define sf(a) scanf("%d", &a) #define sf2(a, b) scanf("%d%d", &a, &b) #define sf3(a, b, c) scanf("%d%d%d", &a, &b, &c) #define sfs(a) scanf("%s", a) #define clr(a, b) memset(a, b, sizeof(a)) using namespace std; const int MAXN = 12; int row, col, beg; char str[MAXN]; int grid[MAXN][MAXN]; int vis[MAXN][MAXN]; const int dr[] = {-1, 0, 1, 0}; const int dc[] = {0, 1, 0, -1}; int main() { freopen("input.txt", "r", stdin); while(sf3(row, col, beg) != EOF && row != 0) { clr(vis, 0); clr(grid, 0); for(int i = 1; i <= row; i++) { sfs(str); for(int j = 1; j <= col; j++) { switch(str[j-1]) { case 'N':grid[i][j] = 0;break; case 'E':grid[i][j] = 1;break; case 'S':grid[i][j] = 2;break; case 'W':grid[i][j] = 3;break; } } } int gr = 1, gc = beg, lr, lc; int tot = 0; vis[gr][gc] = 1; int flag = 1; int sum; while(true) { tot++; lr = gr; lc = gc; gr += dr[grid[lr][lc]]; gc += dc[grid[lr][lc]]; if(gr < 1 || gr > row || gc < 1 || gc > col) { printf("%d step(s) to exit\n", tot); break; } if(vis[gr][gc] == 1 && flag == 1) { flag = 0; sum = tot; } if(vis[gr][gc] == 2) { printf("%d step(s) before a loop of %d step(s)\n", sum + sum - tot, tot-sum); break; } vis[gr][gc]++; } } return 0; } POJ 2993

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> #define sf(a) scanf("%d", &a) #define sf2(a, b) scanf("%d%d", &a, &b) #define sf3(a, b, c) scanf("%d%d%d", &a, &b, &c) #define sfs(a) scanf("%s", a) #define clr(a, b) memset(a, b, sizeof(a)) using namespace std; const int MAXN = 10; char m[MAXN][MAXN]; char str[100]; char a[2] = {'.', ':'}; int main() { freopen("input.txt", "r", stdin); gets(str); for(int i = 7; i < strlen(str); i++) { if(str[i] == ',') { int r = 9 - str[i-1] + '0'; int c = str[i-2] - 'a' + 1; if(str[i-4] == ',' || str[i-4] == ' ') m[r][c] = str[i-3]; else m[r][c] = 'P'; } } if(strlen(str) > 7) { int r = 9 - str[strlen(str)-1] + '0'; int c = str[strlen(str)-2] - 'a' + 1; if(str[strlen(str)-4] == ',' || str[strlen(str)-4] == ' ') m[r][c] = str[strlen(str)-3]; else m[r][c] = 'P'; } gets(str); for(int i = 7; i < strlen(str); i++) { if(str[i] == ',') { int r = 9 - str[i-1] + '0'; int c = str[i-2] - 'a' + 1; if(str[i-4] == ',' || str[i-4] == ' ') m[r][c] = str[i-3] + 32; else m[r][c] = 'p'; } } if(strlen(str) > 7) { int r = 9 - str[strlen(str)-1] + '0'; int c = str[strlen(str)-2] - 'a' + 1; if(str[strlen(str)-4] == ',' || str[strlen(str)-4] == ' ') m[r][c] = str[strlen(str)-3] + 32; else m[r][c] = 'p'; } for(int i = 1; i <= 8; i++) { printf("+---+---+---+---+---+---+---+---+\n"); for(int j = 1; j <= 8; j++) { printf("|%c", a[(i+j)%2]); if(m[i][j] == 0) printf("%c", a[(i+j)%2]); else printf("%c", m[i][j]); printf("%c", a[(i+j)%2]); } printf("|\n"); } printf("+---+---+---+---+---+---+---+---+\n"); return 0; } POJ 2996 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> #include<map> #define sf(a) scanf("%d", &a) #define sf2(a, b) scanf("%d%d", &a, &b) #define sf3(a, b, c) scanf("%d%d%d", &a, &b, &c) #define sfs(a) scanf("%s", a) #define clr(a, b) memset(a, b, sizeof(a)) using namespace std; const int MAXN = 10; char m[MAXN][MAXN]; char str[100]; map<char, int> M; struct Node { char zz; int row, col; Node(int _row = 0, int _col = 0, char _zz = 0):row(_row), col(_col), zz(_zz){} }s1[40], s2[40]; int t1, t2; //* bool cmp1(const Node& p, const Node& q) { if(M[p.zz] != M[q.zz]) return M[p.zz] < M[q.zz]; else if(p.row != q.row) return p.row > q.row; else return p.col < q.col; } bool cmp2 (const Node& p, const Node& q) { if(M[p.zz] != M[q.zz]) return M[p.zz] < M[q.zz]; else if(p.row != q.row) return p.row < q.row; else return p.col < q.col; } //*/ int main() { freopen("input.txt", "r", stdin); M['K'] = 1; M['Q'] = 2; M['R'] = 3; M['B'] = 4; M['N'] = 5; M['P'] = 6; M['k'] = 11; M['q'] = 12; M['r'] = 13; M['b'] = 14; M['n'] = 15; M['p'] = 16; for(int i = 0; i < 34; i++) getchar(); for(int i = 0; i < 8; i++) { getchar(); for(int j = 0; j < 8; j++) { getchar(); m[i+1][j+1] = getchar(); getchar(); getchar(); } getchar(); for(int i = 0; i < 34; i++) getchar(); } for(int i = 1; i <= 8; i++) { for(int j = 1; j <= 8; j++) { //cout << m[i][j]; if(m[i][j] != '.' && m[i][j] != ':') { if(m[i][j] <= 'Z') s1[t1++] = Node(i, j, m[i][j]); else s2[t2++] = Node(i, j, m[i][j]); } } //cout << endl; } sort(s1, s1 + t1, cmp1); sort(s2, s2 + t2, cmp2); printf("White: "); int flag = 1; for(int i = 0; i < t1; i++) { if(flag == 0) printf(","); else flag = 0; if(s1[i].zz != 'P') printf("%c", s1[i].zz); printf("%c%d", s1[i].col + 'a' - 1, 9-s1[i].row); } printf("\n"); printf("Black: "); flag = 1; for(int i = 0; i < t2; i++) { if(flag == 0) printf(","); else flag = 0; if(s2[i].zz != 'p') printf("%c", s2[i].zz - 32); printf("%c%d", s2[i].col + 'a' - 1, 9-s2[i].row); } printf("\n"); return 0; }

    至此,POJ题目分类 初级-一、基本算法已刷完

    POJ题目分类 初级-二、图算法 暂且先放一放

    先准备JSCPC

    转载请注明原文地址: https://ju.6miu.com/read-34918.html

    最新回复(0)