交错匹配
【问题描述】
有两排非负整数,A[1..N],B[1..M],如果A[i]=B[j]=K,那么可以在A[i],B[j]之间连一条线,称为一条K匹配,每个数至多连一条线。另外,每个K匹配都必须跟一个L匹配相交且K≠L!现在要求一个最大的匹配数。
例如:以下两行数的最大匹配数为8。一个数最多只能和一个数连线。
1 2 3 3 2 4 1 5 1 3 5 10
![]() | ![]() | ![]() | ![]() |
3 1 2 3 2 4 12 1 5 5 3
【输入文件】
输入文件名为cross.in。
输入文件第一行包含两个正整数N和M。
第二行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,统计不定方程的非负整数解(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
背景:
这次是杨宽同学非常喜欢的数学题。他是一个很大方的人。所以来和你分享了。
任务:
这个式子是杨宽给你的,他会告诉你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;
}