A.水题,观察下k及其后面是不是都是同样的数字判断是否为-1,否则看前面有多少个和a[k]后面的数字不一样的,来判断需要调整多少次。
B.水题,交换的时候换下标号就行了。
C.有意思的一题,问分数约分的结果,突然记起来看过一张图:
回到正题……
要求n和m在10^5范围内,那么如果先全部分解质因子之后约分,再将结果随机组合乘起来输出就很有可能就会超出这个范围,因此,决定在约分后,该位置的数一定要是约分前在该位置的数的约数,所以就先对所有分子和所有分母都分解质因子,然后对于原来的分子,逐个遍历分解质因子,如果该质因子在分母中的数目大于0,那么就将其约掉,也就是该质因子在分母中的数目减1,如果等于0,说明不能被约掉,就用一个新变量存起来,有不能被约掉的就在这个变量上累乘就行了,最后约分的结果就是这些新变量了。
代码
#include <stdio.h> #include <string.h> #include <algorithm> #include <map> using namespace std; int p[5000]; bool prime[5000]; int a[100005]; int b[100005]; int up; map <int,int> fm; map <int,int> fz; void Prime() { int i,j; memset(prime,0,sizeof(prime)); for (i=2;i<=3500;i++) { if (prime[i]==1) continue; p[up++]=i; for (j=i*i;j<=3500;j+=i) { prime[j]=1; } } } int main() { int i,j,n,m,t,now; up=0; Prime(); scanf("%d%d",&n,&m); for (i=0;i<n;i++) { scanf("%d",&a[i]); t=a[i]; for (j=0;j<up;j++) { if (t==1) break; while(t%p[j]==0) { fm[p[j]]++; t/=p[j]; } } if (t!=1) fm[t]++; } for (i=0;i<m;i++) { scanf("%d",&b[i]); t=b[i]; for (j=0;j<up;j++) { if (t==1) break; while(t%p[j]==0) { t/=p[j]; fz[p[j]]++; } } if (t!=1) fz[t]++; } map <int,int>::iterator it; printf("%d %d\n",n,m); for (i=0;i<n;i++) { t=a[i]; now=1; for (j=0;j<up;j++) { if (t==1) break; while (t%p[j]==0) { if (fz[p[j]]>0) fz[p[j]]--; else now*=p[j]; t/=p[j]; } } if (t!=1) { if (fz[t]>0) fz[t]--; else now*=t; } printf("%d ",now); } printf("\n"); for (i=0;i<m;i++) { t=b[i]; now=1; for (j=0;j<up;j++) { if (t==1) break; while(t%p[j]==0) { if (fm[p[j]]>0) fm[p[j]]--; else now*=p[j]; t/=p[j]; } } if (t!=1) { if (fm[t]>0) fm[t]--; else now*=t; } printf("%d ",now); } printf("\n"); return 0; }
D.突然变简单了……orz
水题,将a数组从小到大排序,将b数组从大到小排序,然后对于b的每个数,找到能够使得与它相加大于等于x而且没被用过的数,然后标记为使用就行了,因为在a中数字是递增的,因此寻找的时候只要扫一遍a数组即可,复杂度O(n)。
ps:最好的名次肯定是No.1了……
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int a[100005]; int b[100005]; bool cmp(int x,int y) { return x<y; } int main() { int i,j,n,k,ans,l,m,cnt; scanf("%d%d",&n,&k); for (i=0;i<n;i++) { scanf("%d",&a[i]); } for (i=0;i<n;i++) { scanf("%d",&b[i]); } sort(a,a+n); sort(b,b+n,cmp); cnt=0; l=0; for (i=n-1;i>=0;i--) { while(l<n && b[i]+a[l]<k) l++; if (l==n) break; cnt++; l++; } printf("1 %d\n",cnt); return 0; }
不解释。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define MOD 1000000007 typedef struct { __int64 m[55][55]; }Matrix; Matrix b; char str[10]; Matrix a; int m; Matrix Mul(Matrix x,Matrix y) { Matrix tag; int i,j,k; for (i=0;i<m;i++) { for (j=0;j<m;j++) { tag.m[i][j]=0; for (k=0;k<m;k++) { tag.m[i][j]=(tag.m[i][j]+(x.m[i][k]*y.m[k][j])%MOD)%MOD; } } } return tag; } int GetNum(char c) { if (c>='a' && c<='z') return c-'a'; return 26+c-'A'; } int main() { int i,j,k; __int64 n,cnt; scanf("%I64d%d%d",&n,&m,&k); for (i=0;i<m;i++) { for (j=0;j<m;j++) { a.m[i][j]=1; } b.m[i][0]=1; } for (i=0;i<k;i++) { scanf("%s",str); a.m[GetNum(str[0])][GetNum(str[1])]=0; } n--; while(n) { if (n&1) b=Mul(a,b); a=Mul(a,a); n>>=1; } cnt=0; for (i=0;i<m;i++) { cnt=(cnt+b.m[i][0])%MOD; } printf("%I64d\n",cnt); return 0; }