【11/3】模拟赛
第一题 方程
【题目描述】
给出非负整数N,统计不定方程x + y ^ 2 + z ^ 3 = n的非负整数解(x,y,z)的数量。
【输入格式】
一行一个数N。
【输出格式】
解得数量。
【样例输入】
5
【样例输出】
6
【数据范围】
N <= 10 ^ 16。
【分析】
首先枚举Z。因为Z可取的范围是最小的。然后剩下的n – z ^ 3设为t。将t开方。向下取整得到的就是在当前z的取值下最大的y的取值。因为随着y的减小x在增大,所以y的最小值就是0。当前z的取值下解的个数就是y的最大值加1(包括0)。
考试时想到了枚举z,然后找到y的最大值。但是没有想到x取0时y有最大值可以直接开方取整的做法。打了两个表二分查找。不过倒是得到了60%的数据。
第二题 方程式
【题目描述】
给出一个字符串,表达一个方程。保证里面系数不会超过1000000000。保证方程偶且只有一个解,而且方程只会有一个未知数X,且X的最高指数也只会有1。
方程中所有的系数都是整数,且系数是1就会被忽略。
只会出现加减,不会出现乘除。
【输入格式】
输入一个字符串。表示方程。
【输出格式】
输出X的解。保留三位小数。
【样例输入】
6x+7x+8x+1=6x+7x+9x
【样例输出】
1.000
【数据范围】
100%方程长度不会超过255。
【分析】
四道题里最简单的模拟。注意x前面的系数是0的情况(虽然这有点不符合常理)。
第三题 Muti
【题目描述】
a1b1 + a2b2 + a3b3 + … + anbn = c这个式子是给出的。且给出c还有a1一直到an(全是正整数)。求出b1到bn到底有多少组非负整数解。
【输入格式】
第一行:n和c。
第二行n个数分别表示a1到an。
【输出格式】
输出总解数(用99983取模)。
【样例输入】
2 4
1 2
【样例输出】
3
【数据范围】
n <= 100,c <= 100000。
【分析】
模型:N个物体。ai是第i个物体的价值。bi是第i个物体取的个数。问多少种方法可以凑成c。动归过程:
for (int i = 1;i <= n;++i)
for (int j = a[i];j <= c;++j)
f[j] += f[j – a[i]];
第四题 交错匹配
【题目描述】
有两排非负整数,A[1…N],B[1…M],如果 A[i]=B[j]=K,那么可以在 A[i],B[j]之间 连一条线,称为一条K 匹配
,每个数至多连一条线。另外,每个K 匹配都必须跟一个 L匹 配相交且K≠L!现在要求一个最大的匹配数。例如:
以下两行数的最大匹配数为 8。一个数最多只能和一个数连线。
【输入格式】
第一行包含两个正整数 N 和M。
第二行 N个自然数表示 A[i]。
第三行 M 个自然数表示 B[i]。
【输出格式】
只有一个数字,即最大匹配数。
【样例输入】
样例输入1 | 样例输入2 |
12 11
1 2 3 3 2 4 1 5 1 3 5 10
3 1 2 3 2 4 12 1 5 5 3
|
4 4
1 1 3 3
1 1 3 3
|
【样例输入】
样例输入1 | 样例输入2 |
8 | 0 |
【分析】
一下为引用dream的题解(有删减)。原文链接:http://ren.meng.meng.blog.163.com/blog/static/2337029720081010419447/
“
- 首先应该是一条匹配线能且只能与一条相交
- 从末状态出发,想方设法缩小要求解的问题。这个需要一点巧妙的思想,头脑清晰时应该可以想出来g[i,j]表示上行a:i个和下行不:j个的最大匹配数,如果要缩小问题的话,可以考虑i-1或j-1,这样就要分情况,也就是所谓的从各个子问题中找一个最优的,这时要做到“不重不漏”。。具体这个问题:g[i,j]:当从a[i]不引线时,g[i,j]=g[i-1,j];(这里包括从b[j]引线和不从b[j]引线两种情况 ,但这个问题是g[i-1,j]需要解决的,所以这里就有了很重要的一点技巧,就是学会“推卸责任”,也就是说要运用子问题这个优势,不要把缩小问题这一步变成全盘考虑所有问题〔枚举〕)当从b[j]不引线时,g[i,j]=g[i,j-1];当从a[i]和b[j]各引一条线时,他俩必然匹配。设a[i]与b[v]匹配,b[j]与a[u]匹配,则g[i,j]=g[u-1,v-1]+2;这样便完美地缩小了所求问题。
- 另外还要建树组v[i,j]和u[i,j],这就是所谓的2次动态规划(应该是第0次),u和v应该要分开求吧~
”
代码
第一题
#include <stdio.h> #include <math.h> long long n,x,y,z,ans,tem; int main() { freopen("equation.in","r",stdin); freopen("equation.out","w",stdout); scanf("%lld",&n); for (z = 0;z <= 215443;++z) { if (z * z * z > n) break; tem = (long long)sqrt(n - z * z * z); ans += tem + 1; } printf("%lld\n",ans); return 0; }
第二题
#include <stdio.h> #include <ctype.h> #include <string.h> #define MAXN 300 char s[MAXN]; double xx,yy; long long len,x,y,wh; bool jia; int main() { freopen("equationagain.in","r",stdin); freopen("equationagain.out","w",stdout); scanf("%s",s); len = strlen(s); for (int i = 0;i < len;++i) if (s[i] == '=') { wh = i; break; } jia = 1; for (int i = 0;i < wh;++i) if (isdigit(s[i])) x = x * 10 + s[i] - '0'; else if (s[i] == 'x') { if (!x) { x = 1; if ((i) && (s[i - 1] == '0')) x = 0; } if (jia) xx += x; else xx -= x; x = 0; } else { if (x) { if (jia) yy -= x; else yy += x; x = 0; } if (s[i] == '+') jia = 1; else jia = 0; } if (x) { if (jia) yy -= x; else yy += x; x = 0; } jia = 1; for (int i = wh + 1;i < len;++i) if (isdigit(s[i])) x = x * 10 + s[i] - '0'; else if (s[i] == 'x') { if (!x) { x = 1; if ((i) && (s[i - 1] == '0')) x = 0; } if (jia) xx -= x; else xx += x; x = 0; } else { if (x) { if (jia) yy += x; else yy -= x; x = 0; } if (s[i] == '+') jia = 1; else jia = 0; } if (x) { if (jia) yy += x; else yy -= x; x = 0; } xx = yy / xx; printf("%.3lf\n",xx); return 0; }
第三题
#include <stdio.h> #define MAXN 11 #define MAXC 100010 #define mmm 999983 int a,f[MAXC]; int n,c; int main() { freopen("muti.in","r",stdin); freopen("muti.out","w",stdout); scanf("%d%d",&n,&c); f[0] = 1; for (int i = 1;i <= n;++i) { scanf("%d",&a); for (int j = a;j <= c;++j) { f[j] += f[j - a]; f[j] %= mmm; } } printf("%d\n",f[c]); return 0; }
第四题
#include <stdio.h> #include <iostream> #define MAXN 1010 using namespace std; int f[MAXN][MAXN],a[MAXN],b[MAXN],u[MAXN][MAXN],d[MAXN][MAXN]; int n,m; int main() { freopen("cross.in","r",stdin); freopen("cross.out","w",stdout); scanf("%d%d",&n,&m); for (int i = 1;i <= n;++i) scanf("%d",&a[i]); for (int i = 1;i <= m;++i) scanf("%d",&b[i]); for (int i = 1;i <= n;++i) for (int j = 1;j <= m;++j) if ((j > 1) && (b[j - 1] == a[i])) u[i][j] = j - 1; else u[i][j] = u[i][j - 1]; for (int j = 1;j <= m;++j) for (int i = 1;i <= n;++i) if ((i > 1) && (a[i - 1] == b[j])) d[j][i] = i - 1; else d[j][i] = d[j][i - 1]; for (int i = 1;i <= n;++i) for (int j = 1;j <= m;++j) { f[i][j] = max(f[i - 1][j],f[i][j - 1]); if (a[i] != b[j]) { int l,r; l = d[j][i]; r = u[i][j]; if ((l > 0) && (r > 0) && (f[l - 1][r - 1] + 2 > f[i][j])) f[i][j] = f[l - 1][r - 1] + 2; } } printf("%d\n",f[n][m]); return 0; }