原文网址:http://blog.csdn.net/yhf_2015/article/details/53453562#t0
DAY1 T1 玩具谜题
题目来源:洛谷 1563
吐槽:
对NOIP出题人“魔法师”英语单词拼错表示(滑稽)。
思路:
模拟操作过程,分类讨论即可。
时间复杂度:O(n+m)
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct node{ int dir; char name[15];};node p[100010];int n, m;int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) scanf("%d%s", &p[i].dir, p[i].name+1); int now = 1; for(int i = 1; i <= m; i ++){ int a, b; scanf("%d%d", &a, &b); if(p[now].dir == 0){ if(a == 0) now = ((now - b) % n + n) % n; else now = (now + b) % n; }else{ if(a == 0) now = (now + b) % n; else now = ((now - b) % n + n) % n; } if(now == 0) now = n; } printf("%s", p[now].name+1); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <cstdio>using namespace std;const int maxn = 300010;struct node{ int begin, end, lca, len;};node p[maxn];int n, m, val[maxn];int _first[maxn], _next[maxn*2], _to[maxn*2], cnt;int ins1[maxn], ins2[maxn], del1[maxn], del2[maxn];int nxt[maxn*4], v[maxn*4], cnt1;int deep[maxn], up[maxn][20];int ans[maxn];int ct1[maxn*2], ct2[maxn*2];inline void add1(int a, int b, int c){ nxt[++cnt1] = ins1[a]; v[ins1[a] = cnt1] = c; nxt[++cnt1] = del1[b]; v[del1[b] = cnt1] = c;}inline void add2(int a, int b, int c){ nxt[++cnt1] = ins2[a]; v[ins2[a] = cnt1] = c; nxt[++cnt1] = del2[b]; v[del2[b] = cnt1] = c;}inline void add(int a, int b){ _next[++cnt] = _first[a]; _to[_first[a] = cnt] = b;}void dfs(int x){ for(int i = 1; i <= 18; i ++){ up[x][i] = up[up[x][i-1]][i-1]; } for(int i = _first[x]; i; i = _next[i]){ if(_to[i] == up[x][0]) continue; up[_to[i]][0] = x, deep[_to[i]] = deep[x]+1; dfs(_to[i]); }}void lca(){ for(int ii = 1; ii <= m; ii ++){ int x = p[ii].begin, y = p[ii].end; if(deep[x] < deep[y]) swap(x, y); if(deep[x] != deep[y]) for(int i = 18; i >= 0; i --) if(deep[up[x][i]] >= deep[y]) x = up[x][i]; if(x != y){ for(int i = 18; i >= 0; i --) if(up[x][i] != up[y][i]) x = up[x][i], y = up[y][i]; x = up[x][0]; } p[ii].lca = x; p[ii].len = deep[p[ii].begin] - deep[x] + deep[p[ii].end] - deep[x]; }}inline void dfs1(int x){ ans[x] = - ct1[deep[x]+val[x]] - ct2[deep[x]-val[x]+n]; for(int i = _first[x]; i; i = _next[i]){ if(_to[i] == up[x][0]) continue; dfs1(_to[i]); } for(int i = ins1[x]; i; i = nxt[i]) ct1[v[i]] ++; for(int i = del1[x]; i; i = nxt[i]) ct1[v[i]] --; for(int i = ins2[x]; i; i = nxt[i]) ct2[v[i]+n] ++; for(int i = del2[x]; i; i = nxt[i]) ct2[v[i]+n] --; ans[x] += ct1[deep[x]+val[x]] + ct2[deep[x]-val[x]+n];}int main(){ scanf("%d%d", &n, &m); for(int i = 1; i < n; i ++){ int a, b; scanf("%d%d", &a, &b); add(a, b), add(b, a); } deep[1] = 1, dfs(1); for(int i = 1; i <= n; i ++) scanf("%d", &val[i]); for(int i = 1; i <= m; i ++) scanf("%d%d", &p[i].begin, &p[i].end); lca(); for(int i = 1; i <= m; i ++){ add1(p[i].begin, up[p[i].lca][0], deep[p[i].begin]); add2(p[i].end, p[i].lca, deep[p[i].end]-p[i].len); } dfs1(1); for(int i = 1; i < n; i ++) printf("%d ", ans[i]); printf("%d", ans[n]); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
代码:
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int inf = 2e9;int n, m, v, e;int a1[2010], a2[2010];double dp[2010][2010][2], dis[310][310], w[2010], ans;int main(){ scanf("%d%d%d%d", &n, &m, &v, &e); for(int i = 1; i <= n; i ++) scanf("%d", &a1[i]); for(int i = 1; i <= n; i ++) scanf("%d", &a2[i]); for(int i = 1; i <= n; i ++) scanf("%lf", &w[i]); for(int i = 0; i <= v; i ++) for(int j = 0; j <= v; j ++) if(i == j) dis[i][j] = 0; else dis[i][j] = inf; for(int i = 1; i <= e; i ++){ int a, b; double c; scanf("%d%d%lf", &a, &b, &c); dis[a][b] = min(dis[a][b], c); dis[b][a] = min(dis[b][a], c); } for(int k = 1; k <= v; k ++) for(int i = 1; i <= v; i ++) for(int j = 1; j <= v; j ++) if(dis[i][j] > dis[i][k]+dis[k][j]) dis[i][j] = dis[i][k]+dis[k][j]; for(int i = 0; i <= n; i ++) for(int j = 0; j <= m; j ++) dp[i][j][0] = dp[i][j][1] = inf; dp[1][0][0] = 0; dp[1][1][1] = 0; for(int i = 2, up; i <= n; i ++){ up = min(i, m); for(int j = 0; j <= up; j ++){ dp[i][j][0] = min(dp[i][j][0], dp[i-1][j][0] +dis[a1[i]][a1[i-1]]); dp[i][j][0] = min(dp[i][j][0], dp[i-1][j][1] +dis[a1[i]][a2[i-1]]*w[i-1] +dis[a1[i]][a1[i-1]]*(1-w[i-1])); if(j-1 >= 0) dp[i][j][1] = min(dp[i][j][1], dp[i-1][j-1][0] +dis[a2[i]][a1[i-1]]*w[i] +dis[a1[i]][a1[i-1]]*(1-w[i])); if(j-1 >= 0) dp[i][j][1] = min(dp[i][j][1], dp[i-1][j-1][1] +dis[a2[i]][a2[i-1]]*w[i]*w[i-1] +dis[a2[i]][a1[i-1]]*w[i]*(1-w[i-1]) +dis[a1[i]][a2[i-1]]*(1-w[i])*w[i-1] +dis[a1[i]][a1[i-1]]*(1-w[i])*(1-w[i-1])); } } ans = inf; for(int i = 0; i <= m; i ++) ans = min(ans, min(dp[n][i][0], dp[n][i][1])); printf("%.2lf", ans); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
代码:
#include <cstdio>#include <iostream>using namespace std;int T, k;int sum[2010][2010], val[2010][2010];int a[10010], b[10010], p1, p2;int main(){ scanf("%d%d", &T, &k); for(int i = 1; i <= T; i ++){ scanf("%d%d", &a[i], &b[i]); p1 = max(p1, a[i]); p2 = max(p2, b[i]); } for(int i = 0; i <= p1; i ++){ for(int j = 0; j <= min(p2, i); j ++){ if(j == 0){val[i][j] = 1;continue;} val[i][j] = (val[i-1][j] + val[i-1][j-1]) % k; if(val[i][j] == 0) sum[i][j] = 1; } } for(int i = 1; i <= p1; i ++){ for(int j = 1; j <= p2; j ++){ sum[i][j] = sum[i-1][j] + sum[i][j-1] + sum[i][j] - sum[i-1][j-1]; } } for(int i = 1; i <= T; i ++){ printf("%d\n", sum[a[i]][b[i]]); } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
代码:
#include <cstdio>#include <iostream>#include <algorithm>#define MAX(a,b) (((a)>(b))?(a):(b))#define MIN(a,b) (((a)<(b))?(a):(b))using namespace std;inline int gt(){ char _ch = ' '; int _num = 0, _op = 1, _ok = 0; while(1){ _ch = getchar(); if(_ch == '-') _op *= -1; else if(_ch >= '0' && _ch <= '9') _num = _num*10 + _ch - '0', _ok = 1; else if(_ok) return _op * _num; } } int n, m, q, u, v, t;int left1;int len[100010], q1[8000010], q2[8000010];int out[1000010], cnt;int main(){ scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t); for(int i = 1; i <= n; i ++) len[i] = gt(); sort(len+1, len+1+n); int p1 = 1, p2 = 0, p3 = 1, p4 = 0, p5 = n, now = 0; for(int i = 1; i <= m; i ++){ if(p5 >= 1 && len[p5] >= MAX(q1[p1], q2[p3])) now = len[p5--] + left1; else if(p1 <= p2 && q1[p1] >= q2[p3]) now = q1[p1++] + left1; else if(p3 <= p4) now = q2[p3++] + left1; if(i%t == 0) out[++cnt] = now; left1 += q; int new1 = ((long long)now*(long long)u)/(long long)v; int new2 = now - new1; q1[++p2] = MAX(new1, new2) - left1; q2[++p4] = MIN(new1, new2) - left1; } for(int i = 1; i <= cnt; i ++) printf("%d ", out[i]); printf("\n"); for(int i = 1, w = 0; i <= n+m; i ++, w = 0){ if(p5 >= 1 && len[p5] >= MAX(q1[p1], q2[p3])) w = len[p5--] + left1; else if(p1 <= p2 && q1[p1] >= q2[p3]) w = q1[p1++] + left1; else if(p3 <= p4) w = q2[p3++] + left1; if(i%t != 0) continue; printf("%d ", w); } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
代码:
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const double eps = 0.000000001;struct point{ double x, y;};int T, n, m, ans = 1e9;point p[25];int num[25][25], dp[300010];int calc(double a, double b){ int res = 0, now = 1; for(int i = 1; i <= n; i ++, now <<= 1){ double t = a*p[i].x*p[i].x+b*p[i].y; if(abs(a*p[i].x*p[i].x+b*p[i].x-p[i].y) < eps){ res |= now; } } return res;}int bits(int x){ int res = 0; for(int i = 1; i <= n; i ++, x >>= 1) if((x&1) == 0) res ++; return res;}int main(){ scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++){ scanf("%lf%lf", &p[i].x, &p[i].y); } memset(dp, 63, sizeof(dp)); memset(num, 0, sizeof(num)); ans = 1e9; for(int i = 1; i <= n; i ++){ for(int j = i+1; j <= n; j ++){ if(i == j) continue; if(abs(p[i].x-p[j].x) < eps) continue; double a = (p[i].y*p[j].x-p[j].y*p[i].x)/(p[i].x*p[i].x*p[j].x-p[j].x*p[j].x*p[i].x); if(a >= 0) continue; double b = (p[i].y-a*p[i].x*p[i].x)/p[i].x; num[i][++num[i][0]] = calc(a,b); } } int MAX = (1<<n)-1; dp[0] = 0; for(int i = 0; i <= MAX; i ++){ int now = 0; for(int j = 1, w = 1; j <= n; j ++, w <<= 1){ if((w&i) == 0){now = j;break;} } if(now == 0) continue; dp[i|(1<<(now-1))] = min(dp[i|(1<<(now-1))], dp[i] + 1); for(int j = 1; j <= num[now][0]; j ++){ dp[i|num[now][j]] = min(dp[i|num[now][j]], dp[i] + 1); } } printf("%d\n", dp[MAX]); } return 0;}