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;
}
E.水题,入门的矩阵递推。
不解释。
#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;
}
本文解析了五道编程题目,包括简单的数组操作、分数约分、寻找最优配对等,并给出了具体的实现代码。
508

被折叠的 条评论
为什么被折叠?



