NOIP2000普及组
第一题 计算器的改良
大模拟,好好处理字符串。
第二题 税收与补贴
略过。
第三题 乘积最大
区间动归,记得高精度。
第四题 单词接龙
带字符处理的深搜。
代码
第一题
#include <stdio.h> #include <ctype.h> #include <string.h> #define MAXN 300 char s[MAXN],c; double xx,yy,x; bool jia,havenum; int wh; int main() { scanf("%s",s); jia = 1; for (int i = 0;i < strlen(s);++i) if (s[i] == '=') { wh = i; break; } for (int i = 0;i < wh;++i) if (isdigit(s[i])) { havenum = 1; x = x * 10 + s[i] - '0'; } else { if (isalpha(s[i])) { c = s[i]; if ((!havenum) && (!x)) x = 1; if (jia) xx += x; else xx -= x; havenum = 0; x = 0; } else { if (havenum) if (jia) yy -= x; else yy += x; if (s[i] == '+') jia = 1; else jia = 0; x = 0; } } if (havenum) if (jia) yy -= x; else yy += x; x = 0; havenum = 0; jia = 1; for (int i = wh + 1;i < strlen(s);++i) if (isdigit(s[i])) { havenum = 1; x = x * 10 + s[i] - '0'; } else { if (isalpha(s[i])) { c = s[i]; if ((!havenum) && (!x)) x = 1; if (jia) xx -= x; else xx += x; havenum = 0; x = 0; } else { if (havenum) if (jia) yy += x; else yy -= x; if (s[i] == '+') jia = 1; else jia = 0; x = 0; } } if (havenum) if (jia) yy += x; else yy -= x; printf("%c=%.3lf\n",c,yy / xx); return 0; }
第三题
#include <stdio.h> #include <string.h> #define MAXL 310 #define MAXN 50 #define MAXM 10 struct ss { int g[MAXL]; } f[MAXN][MAXM],a[MAXN][MAXN]; char s[MAXN]; int n,m; ss bigger(ss a,ss b) { if (a.g[0] < b.g[0]) return b; if (a.g[0] > b.g[0]) return a; for (int i = a.g[0];i > 0;--i) { if (a.g[i] < b.g[i]) return b; if (a.g[i] > b.g[i]) return a; } return a; } ss cheng(ss a,ss b) { ss c; memset(c.g,0,sizeof(c.g)); for (int i = 1;i <= a.g[0];++i) { int x = 0; for (int j = 1;j <= b.g[0];++j) { c.g[i + j - 1] += a.g[i] * b.g[j] + x; x = c.g[i + j - 1] / 10; c.g[i + j - 1] %= 10; } if (x) c.g[i + b.g[0]] += x; } c.g[0] = a.g[0] + b.g[0]; while ((c.g[0] > 1) && (!c.g[c.g[0]])) --c.g[0]; return c; } void out(ss a) { for (int i = a.g[0];i > 0;--i) printf("%d",a.g[i]); } int main() { scanf("%d%d",&n,&m); ++m; scanf("%s",s); for (int i = n;i > 0;--i) s[i] = s[i - 1]; for (int i = n;i > 0;--i) { a[i][i].g[0] = 1; a[i][i].g[1] = s[i] - '0'; for (int j = i - 1;j > 0;--j) { a[j][i] = a[j + 1][i]; a[j][i].g[++a[j][i].g[0]] = s[j] - '0'; } } for (int i = 1;i <= n;++i) f[i][1] = a[1][i]; for (int i = 1;i <= n;++i) for (int j = 2;j <= m && j <= i;++j) for (int k = j - 1;k < i;++k) f[i][j] = bigger(f[i][j],cheng(f[k][j - 1],a[k + 1][i])); out(f[n][m]); return 0; }
第四题
#include <stdio.h> #include <string.h> #define MAXN 21 struct ss { char s[300]; int len,time; } a[MAXN]; int n,ans; char te[30000010]; void find(int x) { if (x > ans) ans = x; for (int i = 1;i <= n;++i) if (a[i].time < 2) for (int j = 1;j < a[i].len;++j) { if (x - j < 0) break; bool can = 1; for (int k = 1;k <= j;++k) if (te[x - j + k] != a[i].s[k]) { can = 0; break; } if (can) { ++a[i].time; for (int k = j + 1;k <= a[i].len;++k) te[x + k - j] = a[i].s[k]; find(x + a[i].len - j); --a[i].time; } } } int main() { scanf("%d",&n); for (int i = 1;i <= n;++i) { scanf("%s",a[i].s); a[i].len = strlen(a[i].s); for (int j = a[i].len;j > 0;--j) a[i].s[j] = a[i].s[j - 1]; } for (int i = 1;i <= n;++i) { for (int j = 1;j <= a[i].len;++j) te[j] = a[i].s[j]; ++a[i].time; find(a[i].len); } printf("%d\n",ans); return 0; }