看代码写程序
看程序写结果(program) Time Limit:1000ms Memory Limit:64MB
题目描述 LYK 最近在准备 NOIP2017 的初赛,它最不擅长的就是看程序写结果了,因此它拼命地 在练习。 这次它拿到这样的一个程序:
c++:="" pcanf(“%d”,&n);
="" for="" (i="1;" i<="n;" i++)"
=" scanf(“%d”,&a[i]);
="" (j="1;" j<="n;" j++)
="" (k="1;" k<="n;" k++)
="" (l="1;" l<="n;" l++)
="" if="" (a[i]="=a[j]" &&="" a[i]<a[k]="" a[k]="=a[l])"
ans="(ans+1)%1000000007;" printf(“%d\n”,ans);="" lyk=""
知道了所有输入数据,它想知道这个程序运行下来会输出多少。
输入格式(program.in)="" 第一行一个数="" n,第二行="" n="" 个数,表示="" ai。=""
输出格式(program.out)="" 一个数表示答案。=""
对于="" 20%的数据="" n<="50。" 40%的数据="" 60%的数据="" 100%的数据="" 其中均匀分布着="" 50%的数据不同的="" ai="" 个数<="10,对于另外" 个="" 数="">=n/10。
思路:
一道简单的组合数类题目,因为样例错了耽误了点时间。
求出对于某个数单个组合有多少种,然后把不同数的组合乘起来,加个前缀和优化就A了
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; long long ans,f[100005]; int i,n,a[100005],sum; const int MOD=1000000007; int main() { freopen("program.in","r",stdin); freopen("program.out","w",stdout); scanf("%d",&n); for (i=1; i<=n; i++) scanf("%d",&a[i]); sort(a+1,a+n+1); sum=1;f[1]=1; for(int i=2;i<=n;i++) { f[i]=f[i-1]; if(a[i]==a[i-1]) { f[i]=(f[i]+2*sum+1)%MOD; sum++; }else { sum=1; f[i]++; } } sum=0; for(int i=n;i>=2;i--) { if(a[i+1]==a[i]) sum++; else sum=1; if(a[i]!=a[i-1]) ans=(ans+f[i-1]*sum%MOD*sum)%MOD; } cout<<ans<<endl; return 0; }