zoukankan      html  css  js  c++  java
  • 2018 Multi-University Training Contest 4

    累惹。

    B. Harvest of Apples

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6333

    题意:求∑(i=0,m) C(n,m)。

    分析:定义S(n,m)=∑(i=0,m) C(n,m)。可以知道:

    S(n,m)=S(n,m-1)+C(n,m),S(n-m)=S(n-1,m-1)+S(n-1,m)=2*S(n-1,m-1)+C(n-1,m)。

    由此可以推导出,由S(n,m)到S(n-1,m),S(n+1,m),S(n,m-1),S(n,m+1)的式子为:

    S(n-1,m)=(S(n,m)+C(n-1,m))/2

    S(n+1,m)=2*S(n,m)-C(n,m)

    S(n,m-1)=S(n,m)-C(n,m)

    S(n,m+1)=S(n,m)+C(n,m+1)

    得到了四个方向的状态转移式,因此,可以用莫队离线处理。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+10;
     4 const int mod=1e9+7;
     5 typedef long long ll;
     6 struct point{
     7     int n,m,block,id;
     8 }q[maxn]; 
     9 ll fac[maxn],inv[maxn],ans[maxn];
    10 int res,Block;
    11 void init(){
    12     inv[0]=inv[1]=1;
    13     for (int i=2;i<maxn;i++)
    14         inv[i]=(mod-mod/i)*inv[mod%i]%mod; 
    15 }
    16 int comp(point p,point q){
    17     return p.block<q.block || p.block==q.block && p.m<q.m;
    18 }
    19 
    20 int main(){
    21     init();
    22     int t;
    23     cin >> t;
    24     Block=(int)(sqrt(t));
    25     for (int i=0;i<t;i++){
    26         cin >> q[i].n >> q[i].m;
    27         q[i].id=i;
    28         q[i].block=q[i].n/Block;
    29     }
    30     sort(q,q+t,comp);
    31     ll n=0,m=0,nc=1,res=1;
    32     for (int i=0;i<t;i++){
    33         int nn=q[i].n,nm=q[i].m;
    34         while (nn<n){
    35             nc=nc*(n-m)%mod*inv[n]%mod;
    36             res=(res+nc)%mod*inv[2]%mod;
    37             n--;
    38         }
    39         while (nn>n){
    40             res=(res*2%mod-nc+mod)%mod;
    41             nc=nc*(n+1)%mod*inv[n+1-m]%mod;
    42             n++;
    43         }
    44         while (nm<m){
    45             res=(res-nc+mod)%mod;
    46             nc=nc*m%mod*inv[n-m+1]%mod;
    47             m--; 
    48              
    49         }
    50         while (nm>m){
    51             nc=nc*(n-m)%mod*inv[m+1]%mod;
    52             res=(res+nc)%mod;
    53             m++;
    54         }
    55         ans[q[i].id]=res;
    56     }
    57     for (int i=0;i<t;i++) cout << ans[i] << endl;
    58     return 0;
    59 } 
    hdoj6333

    D. Nothing is Impossible

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6335

    题意:有若干道题,每题有1个正确选项,b个错误选项,问一个最优决策使得winner得分最大。

    分析:如果仅有 1 道题,至少有一个人做对这题需要有 错误答案个数 + 1 个人。那么容易发现在每道题正确答案只有一个的情况下,如果 nn 道题中存在 ss 道题,使得学生人数 mm 不少于每道题 错误答案个数 + 1 相乘的结果,那么一定有人能够得到 ss 分。故我们将题目按错误答案个数从小到大排序,找到最大的 pp 满足就是答案。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=110;
     4 struct node{int a,b,num;}a[N];
     5 bool cmp(node a,node b){return a.num<b.num;}
     6 int main(){
     7     int t,n,m;scanf("%d",&t);
     8     while(t--){
     9         scanf("%d%d",&n,&m);
    10         for(int i=1;i<=n;i++) scanf("%d%d",&a[i].a,&a[i].b),a[i].num=a[i].a+a[i].b;
    11         sort(a+1,a+n+1,cmp);
    12         int tmp=m;int cnt=-1;
    13         for(int i=1;i<=n;i++){
    14             int num=a[i].num;
    15             int nn=tmp/num;
    16             tmp=nn*a[i].a;
    17             if(tmp<1) break;
    18             cnt=i;
    19         }
    20         printf("%d
    ",cnt);
    21     }
    22     return 0;
    23 }
    hdoj6335

    E. Matrix from Arrays

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6336

    题意:根据题意构造一个矩阵,求子矩阵和。

    分析:打表发现矩阵有循环节。n为奇数时循环节为n*n,n为偶数时循环节为2*n*2*n。求出循环节二维前缀和,再扩展到普通矩阵求和即可。

     1 #include<iostream>
     2 #include<cstring>
     3 #define maxn 500
     4 using namespace std;
     5 typedef long long ll;
     6 int mp[maxn][maxn],a[maxn];
     7 int L;
     8 void init(){
     9     int cursor = 0;
    10     for (int i = 0;i<4*L; ++i) {
    11         for (int j = 0; j <= i; ++j) { 
    12             mp[j][i - j] = a[cursor];
    13             cursor = (cursor + 1) % L;
    14         }
    15     }
    16     L*=2;
    17     for (int i=0;i<L;i++)
    18         for (int j=0;j<L;j++){
    19             if (i) mp[i][j]+=mp[i-1][j];
    20             if (j) mp[i][j]+=mp[i][j-1];
    21             if (i && j) mp[i][j]-=mp[i-1][j-1];
    22          }
    23 }
    24 ll calc(int x,int y){
    25     if (x<0 || y<0) return 0;
    26     ll res=0;
    27     res=1ll*mp[L-1][L-1]*(x/L)*(y/L)+1ll*mp[x%L][L-1]*(y/L)+1ll*mp[L-1][y%L]*(x/L)+1ll*mp[x%L][y%L];
    28     return res;
    29 }
    30 ll slove(){
    31     int l1,r1,l2,r2;
    32     ll res=0;
    33     cin >> l1 >> r1 >> l2 >> r2;
    34     res=calc(l2,r2)-calc(l1-1,r2)-calc(l2,r1-1)+calc(l1-1,r1-1);
    35     return res;
    36 }
    37 int main(){
    38     ios::sync_with_stdio(false);
    39     cin.tie(0);cout.tie(0);
    40     int t,q;
    41     cin >> t;
    42     while (t--){
    43         cin >> L;
    44         for (int i=0;i<L;i++) cin >> a[i];
    45         init();
    46         cin >> q;
    47         while (q--){
    48             ll ans=slove();
    49             cout << ans << endl;
    50         }
    51     }
    52     return 0;
    53 }
    hdoj6336

    K. Expression in Memories

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6342

    题意:在?处填入数字0-9或+,*使得表达式合法。

    分析:填入1或+即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 bool is1(char c){
     4     return c=='+'||c=='*';
     5 }
     6 int main(){
     7     std::ios::sync_with_stdio(false); 
     8     int t;string s;cin>>t;
     9     while(t--){
    10         cin>>s;s='+'+s;int len=s.size();
    11         for(int i=1;i<len;i++){
    12             if(s[i]=='?'){
    13                 if(s[i-1]=='0'&&(s[i-2]=='+'||s[i-2]=='*')) s[i]='+';
    14                 else s[i]='1';
    15             }
    16         }
    17         int flag=1;
    18         for(int i=1;i<len;i++){
    19             if(is1(s[i])&&is1(s[i-1])) flag=0;
    20             if(i==len-1) break; 
    21             if(is1(s[i-1])&&s[i]=='0'&&!is1(s[i+1])) flag=0;
    22         }
    23         string ans="";
    24         for(int i=1;i<len;i++) ans+=s[i];
    25         if(is1(s[len-1])) flag=0;
    26         if(flag) cout<<ans<<"
    ";
    27         else cout<<"IMPOSSIBLE"<<"
    ";
    28     }
    29     return 0;
    30 }
    hdoj6342

    L. Graph Theory Homework

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6343

    题意:起点1,终点n,中间可经过任意点。求1-n的最小距离。

    分析:容易证明:|sqrt(a)| + |sqrt(b)| > |sqrt(a+b)| ,边权满足三角不等式,故直接从1-n距离最小。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #define maxn 100005
     5 using namespace std;
     6 int a[maxn];
     7 int main(){
     8     ios::sync_with_stdio(false);
     9     cin.tie(0);cout.tie(0); 
    10     int t,n;
    11     cin >> t;
    12     while (t--){
    13         cin >> n;
    14         for (int i=1;i<=n;i++) cin >> a[i];
    15         int ans=(int)sqrt(abs(a[1]-a[n]));
    16         cout << ans << endl;
    17     }
    18     return 0;
    19 } 
    hdoj6343
  • 相关阅读:
    IOS之推送通知(本地推送和远程推送)
    IOS,苹果内购和添加广告
    CSS3选择器、背景、边框、文本
    CSS2D旋转、过渡、动画
    JavaScript Array、Date、String
    那些不常用却很有的CSS
    纯CSS打造兼容各种浏览器的几何图形
    安装 SQLManagementStudio_x86_CHS(SQL Server Management Studio) 老提示重启的解决办法
    关于使用Html.RenderPartial和Html.Partial显示分部视图时提示参数错误的BUG
    学习从实践开始之jQuery插件开发:对话框插件开发
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/9425548.html
Copyright © 2011-2022 走看看