A:简单题;我们可以把点换成段处理,然后枚举段看是否被霸占了;
#include<iostream>
#include< string> #include<math.h> #include<algorithm> using namespace std; int b[ 1000]; int main() { int n; cin>>n; int l,r; cin>>l>>r; for ( int i=l;i<r;i++) b[i+ 1]= 1; for ( int i= 2;i<=n;i++) { cin>>l>>r; for ( int i=l;i<r;i++) if (b[i+ 1]) b[i+ 1]= 0; } int sum= 0; for ( int i= 1;i<= 1000;i++) if (b[i]) sum++; cout<<sum<<endl; return 0;
}
B:数学题,题目越长越简单,这个道理没错啊,开始没推出来,猜了个结论;
可以达到的值的范围是[L,R],[2*L,2*R],[3*L,3*R],......[X*L,X*R],只可能是这些结果。。
所以XL<=ni<=X*R;
结论就是:
if (a/l*l<=a&&a/l*r>=a) cout<<"Yes"<
C题:题目简单,但是很难,没做出来。。。。
大概思路是:先将每个书分解质因数CI,然后将这CI个质因数分配到N个盒子里,组合数学求这个方案数:AI=C(ci+n-1,n-1);ps:我还推不出这个等式啊。。。。。
ANS=a[i]乘积%10000000007;
对了求C(N,M)=C(N-1,M-1)+C(N,M-1)可以运用数组求出
#include<iostream>
#include<algorithm> #include< string.h> #include<map> using namespace std; map< int, int> v; const int mod= 1000000007; int c[ 18000][ 1000]; int n,a[ 1000],cnt= 0; long long num[ 100000]; void getnum( int x) { for ( int i= 2;i*i<=x;i++) { while (x%i== 0) { if (v.count(i)) { num[v[i]]++; x/=i; } else{ v[i]=++cnt; num[v[i]]++; x/=i; } } } if (x== 1) return; if (v.count(x)) num[v[x]]++; else { v[x]=++cnt; num[v[x]]++; } } int main() { c[ 0][ 0]= 1; for ( int i= 1;i<= 17000;i++) for ( int j= 0;j<=i&&j<= 1000;j++) { if (j== 0||j==i) c[i][j]= 1; else c[i][j]=(c[i- 1][j- 1]+c[i- 1][j])%mod; } int n; cin>>n; for ( int i= 1;i<=n;i++) { int x; cin>>x; getnum(x); } long long ans= 1; for ( int i= 1;i<=cnt;i++) ans=ans*c[num[i]+n- 1][n- 1]%mod; cout<<ans<<endl; return 0; }
D题:个人认为这题比C简单,赛后wo耐心的把公式推出了,其实也比较好推的
ANS:(v[i]-2)u[i]+2*(n-v[i]+1) / (2*u[i]*v[i]);
卡在求U[I],V[I];
居然有这样的神结论:因为10^9的素数很密集,可以直接暴力求解,吓尿了。。。。
#include<iostream> #include< string.h> #include<algorithm> #include<math.h> using namespace std; int prime[ 100002]; int cnt= 0; int vis[ 100000+ 5]; void init() { for ( int i= 2;i<= 100000;i++){ if (vis[i]) continue; prime[++cnt]=i; for ( int j=i+i;j<= 100000;j+=i) vis[j]= 1; } } long long gcd( long long x, long long y) { if (x<y) swap(x,y); if (x%y== 0) return y; return gcd(y,x%y); } long long find1( long long x) { while ( 1) { int i= 1; while (i<=cnt) { if (x%prime[i]== 0&&x!=prime[i]) {x--;i= 1; continue;} i++; } return x; } } long long find2( long long x) { x++; while ( 1) { int i= 1; while (i<=cnt) { if (x%prime[i]== 0&&x!=prime[i]) {x++;i= 1; continue;} i++; } return x; } } int main() { int n; init(); cin>>n; for ( int i= 1;i<=n;i++) { int x; cin>>x; long long l=find1(x),r=find2(x); long long a=(l- 2)*r+ 2*(x-l+ 1),b= 2*(l*r); cout<<a/gcd(a,b)<< " / "<<b/gcd(a,b)<<endl; } return 0;
}
可见我弱的一般性。。。