交错匹配

【问题描述】

有两排非负整数,A[1..N],B[1..M],如果A[i]=B[j]=K,那么可以在A[i],B[j]之间连一条线,称为一条K匹配,每个数至多连一条线。另外,每个K匹配都必须跟一个L匹配相交且KL!现在要求一个最大的匹配数。

例如:以下两行数的最大匹配数为8。一个数最多只能和一个数连线。

1 2 3 3 2 4 1 5 1 3 5 10

               
  clip_image001   clip_image002   clip_image003   clip_image003[1]

3 1 2 3 2 4 12 1 5 5 3

【输入文件】

输入文件名为cross.in。

输入文件第一行包含两个正整数NM

第二行N个自然数表示A[i],

第三行M个自然数表示B[i]。

【输出文件】

输出文件名为cross.out。输出文件只有一个数字,即最大匹配数。

【输入样例I】

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

【输出样例I】

8

【输入样例II】

4 4
1 1 3 3

1 1 3 3

【输出样例II】

0

【数据规模】

30%的数据满足N,M ≤ 30;

60%的数据满足N,M ≤ 200;

100%的数据满足N,M ≤ 1000, 0<所有数<=32767。

  1: #include <cstdio>
  2: #include <cstring>
  3: int n,m;
  4: int a[1010],b[1010];
  5: int f[1010][1010];
  6: int last;
  7: int s[32769];
  8: int max(int a,int b){return a>b?a:b;}
  9: int main(){
 10:     freopen("cross.in","r",stdin);
 11:     freopen("cross.out","w",stdout);
 12:     scanf("%d%d\n",&n,&m);
 13:     for (int i=1;i<=n;i++){
 14:         scanf("%d",&a[i]);
 15:     }
 16:     for (int i=1;i<=m;i++){
 17:         scanf("%d",&b[i]);
 18:     }
 19:     memset(s,8,sizeof(s));
 20:     for (int i=1;i<=n;i++){
 21:         last=0;
 22:         for (int j=1;j<=m;j++){
 23:             f[i][j]=max(f[i-1][j],f[i][j-1]);
 24:             if (a[i]!=b[j]){
 25:                if (last>0 && s[b[j]]<i) f[i][j]=max(f[i][j],f[s[b[j]]-1][last-1]+1);
 26:             }else last=j;
 27:         }
 28:         s[a[i]]=i;
 29:     }
 30:     printf("%d\n",f[n][m]*2);
 31:     return 0;
 32: }
 33: 

 

方程

【问题描述】

给出非负整数N,统计不定方程clip_image005的非负整数解(x,y,z)的数量。

【输入文件】

输入文件equation.in包含一个非负整数N

【输出文件】

输出文件为equation.out。包含一个非负整数表示解的数量。

【输入样例】

5

【输出样例】

6

【样例解释】

6组解分别为(x,y,z)=(0,2,1),(1,2,0),(3,1,1),(4,0,1),(4,1,0),(5,0,0).

【数据规模和约定】

40%的数据中N≤10000;

60%的数据中N≤108

100%的数据中N≤1016

#include <cstdio>
#include <cmath>
__int64 n;
__int64 ans;
int main(){
    freopen("equation.in","r",stdin);
    freopen("equation.out","w",stdout);
    scanf("%I64d",&n);
    for (__int64 z=0;z*z*z<=n;z++){
        __int64 t=n-z*z*z;
        __int64 y=(int)sqrt(t)+1;
        ans+=y;
    }
    printf("%I64d\n",ans);
    return 0;
}

题目: Equation

时限: 1s

内存: 64M

文件名:Equation.xxx

背景:

杨宽又一次懒惰了,他不喜欢解方程。

那么如此好学的杨宽为什么不喜欢解方程呢?

答案太明显了,方程太简单了不需要解。

不过对于其他人来说就不一定了。

任务:

给出一个字符串,表达一个方程。

保证里面系数不会超过 1000000000 。

保证方程有且只有一解,而且方程只会有一个未知数X,且X的最高指数也只会有1。

方程中所有的系数都是整数,且系数是1就会被省略。

只会出现+、-符号,不会出现乘除。

输入:

输入一个字符串。表示方程。

输出:

输出X的解。保留三位小数。

样例:

In:

6x+7x+8x+1=6x+7x+9x

Out:

1.000

数据:

100% 方程长度不会超过255。

#include <cstring>
#include <cstdio>
char s[300];
int left,right,mid;
int lnum,rnum;
int num;
int flag;
int main(){
    freopen("equationagain.in","r",stdin);
    freopen("equationagain.out","w",stdout);
    scanf("%s\n",s);
    int t=strlen(s);
    for (int i=0;i<t;i++){
        if (s[i]=='='){
                       mid=i;
                       break;
        }
    }
    flag=1;
    num=0;
    for (int i=0;i<mid;i++){
        if (s[i]=='-'){
                       flag=-1;
                       num=0;
        }else 
        if (s[i]=='+'){
              flag=1;
              num=0;
        }else
        if (s[i]>='0' && s[i]<='9'){
                      num=num*10+(s[i]-'0');
                      if (s[i+1]=='x'){
                                       left+=num*flag;
                                       num=0;
                                       i++;
                      }else if (s[i+1]<'0' || s[i+1]>'9')
                                if (s[i+1]!='x'){
                                                 lnum+=num*flag;
                                                 num=0;
                                }
        }else
        if (s[i]=='x'){
                       left+=flag;
        }
    }
    flag=1;
    num=0;
    for (int i=mid+1;i<t;i++){
        if (s[i]=='-'){
                       flag=-1;
                       num=0;
        }else 
        if (s[i]=='+'){
              flag=1;
              num=0;
        }else
        if (s[i]>='0' && s[i]<='9'){
                      num=num*10+(s[i]-'0');
                      if (s[i+1]=='x'){
                                       right+=num*flag;
                                       num=0;
                                       i++;
                      }else if (s[i+1]<'0' || s[i+1]>'9')
                                if (s[i+1]!='x'){
                                                 rnum+=num*flag;
                                                 num=0;
                                }
        }else
        if (s[i]=='x'){
                       right+=flag;
        }
    }
    double ans=(double)(rnum-lnum)/(double)(left-right);
    printf("%.3lf\n",ans);
    return 0;
}

题目: Muti

时限: 1s

内存: 64M

文件名:Muti.xxx

背景:

这次是杨宽同学非常喜欢的数学题。他是一个很大方的人。所以来和你分享了。

任务:

clip_image007

这个式子是杨宽给你的,他会告诉你c还有a1一直到an(全是正整数)。

你的任务就是要求出这个b1到bn有多少组非负整数解。

输入:

输入第一行是n和c

第二行n个数分别表示 a1到an。

输出:

输出总解数(用999983取模)。

样例:

In:

2 4

1 2

Out:

3

数据:

30% n≤10 c≤100

100% n≤100 c≤100000

#include <cstdio>
#define M 999983
int n,c;
int f[100100];
int x;
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",&x);
        for (int j=x;j<=c;j++){
            f[j]=(f[j]+f[j-x]) % M;
        }
    }
    printf("%d\n",f[c]);
    return 0;
}