2018 FJUT ACM 校赛 F 题 第六集:跟你订下约定的小A命令你,封印解除!
第六集:跟你订下约定的小A命令你,封印解除!
TimeLimit:1000MS MemoryLimit:128MB
64-bit integer IO format:%lld
Problem Description
"原来我最少要能跳这么远,才能跳过去啊,那么问题又来了~~~" 小晋边抖腿边说
"别说了,没有什么是打一顿不能解决的,如果有,那就两顿!!!"
"别别别,这真是最后一个问题了,我的力量还没觉醒,被封印在体内了!只要你能帮我解开封印,一切问题都不是问题"
"好吧,我最后相信你一次,怎么解开封印,你说吧"
"本大仙当初也是个风流倜傥的翩翩公子balabalabala....."
"说重点!" 小A已经撸起了袖子
"得得得,一点情趣都没有,我给你说得通俗一点
给定一个大小为n的整数数组,a1,a2...an,将其中每个元素转换为其他数的乘积,
我的能力就能够得到解封"
Input
多组输入,请处理到EOF
每组数据第一行为一个整数n。(2<=n<=100000)
接下来一行有n个整数,a1,a2...an,其中每个数的范围大于等于0且不超过10。
结果可能很大,请对每个数取余1000000007。
Output
输出一行整数,代表每个数由其他n-1个数的乘积对1000000007取余后的结果。
SampleInput
5 1 2 3 4 5 5 2 2 2 2 2
SampleOutput
120 60 40 30 24 16 16 16 16 16
hint 120=2*3*4*5 60=1*3*4*5 40=1*2*3*5 24=1*2*3*4
【思路】:
因为每个数的范围大于等于0且不超过10,
所以我有一个奇葩的思路,我开了个标记数组flag【10】
标记出现的次数。
它的询问最多就10种情况,那我就先把所有的情况预处理放到一个答案数组里面
预处理就是把flag【i】(i 从0到10)
减一,然后运算出答案。
运算完再加回去。把运算答案保存。
result【i】,i代表缺少的值。
每次询问只要输出result【缺少的值】就ojbk了
附上代码(运行时间:64ms)
#include<cstdio> #include<cstring> int math[100005]; int flag[15]; long long maths[15]; const long long maxn=1000000007; int main() { int n; while(~scanf("%d",&n)) { memset(flag,0,sizeof(flag)); for(int i=0; i<n; i++) { //int a; scanf("%d",&math[i]); flag[math[i]]++; } for(int i=0; i<=10; i++) { flag[i]--; long long sum=1; for(int j=0; j<=10; j++) { int b; b=flag[j]; while(b>0) { //printf("...\n"); sum=sum*(j); sum=sum%maxn; //printf("%d\n",sum); b--; } //printf("%d\n",sum); } maths[i]=sum; flag[i]++; } for(int i=0; i<n; i++) {if(i!=n-1)printf("%lld ",maths[math[i]]); else printf("%lld\n",maths[math[i]]); } } return 0;}