【11/3】模拟赛

第一题 方程

【题目描述】

给出非负整数N,统计不定方程x + y ^ 2 + z ^ 3 = n的非负整数解(x,y,z)的数量。

 

【输入格式】

一行一个数N。

 

【输出格式】

解得数量。

  

【样例输入】

5

 

【样例输出】

 

【数据范围】

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/

  1. 首先应该是一条匹配线能且只能与一条相交
  2. 从末状态出发,想方设法缩小要求解的问题。这个需要一点巧妙的思想,头脑清晰时应该可以想出来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;这样便完美地缩小了所求问题。
  3. 另外还要建树组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;
}


posted @ 2010-11-03 14:46  Sephiroth.L.  阅读(512)  评论(4编辑  收藏  举报