zoukankan      html  css  js  c++  java
  • 2019西安多校联训 Day4

       T1

      大水题!!难度简单,显然的贪心策略即可,but...

      思路:首先我们按与i点作战后活下来的士兵排序,然后

    若当前剩余兵力足够直接减掉战斗死亡人数,如果不够就加

    够再打它,但是!我们在考完试观察测试点时发现了这样一组

    测试点:

      2

      7 4

      5 1

      emmm,这组测试点是什么意思呢??我们只需要4个人就可以

    打下这座城市,但打这个城市的4个人中需要阵亡7人!(???喵喵喵???)

    这就很尴尬了,当我们遇到这样的点时,我们只需凑够阵亡人数即可

    不用管剩余人数(显然无人生还...)

    T1-
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct node{
     4     long long x,y;
     5 }a[100010];
     6 long long n,mlast,ans;
     7 long long T;
     8 bool cmp(node p,node q){
     9     return (p.y-p.x)>(q.y-q.x); 
    10 }
    11 inline void solve(){
    12     for(register int i=1;i<=n;i++){
    13         if(a[i].y<a[i].x&&mlast<a[i].x){ans+=(a[i].x-mlast),mlast=0;continue;}
    14         else if(a[i].y<a[i].x&&mlast>=a[i].x){mlast-=a[i].x;continue;} 
    15         if(mlast>=a[i].y){
    16             mlast-=a[i].x;
    17             continue;
    18         }
    19         else if(mlast<a[i].y){
    20             ans+=a[i].y-mlast;
    21             mlast=a[i].y-a[i].x;
    22         }
    23     }
    24 }
    25 int main(){
    26     scanf("%lld",&T);
    27     while(T--){
    28         memset(a,0,sizeof(a));
    29         ans=0;mlast=0;
    30         scanf("%lld",&n);
    31         for(register int i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y);
    32         sort(a+1,a+n+1,cmp);
    33         solve();
    34         printf("%lld
    ",ans);
    35     }
    36     return 0;
    37 }
    X国的军队

       T2

      这道题是一道数论题,对没有学过组合数同学非常不友好

    (当然对我这种学过组合数但是只会杨辉三角的人也不友好....)

    难度中等,因为有规律鸭

      思路:首先我们需要知晓组合数的定义如下图

        

      此乃组合数,那我们可以好好看题了,根据二项式定理我们知道

    C0n+C1n+C2n+...Cnn=2^n;这是无比显然的,但平方过后规律产生了

    变化,由作业帮可得(Cn0)^2+(Cn1)^2+(Cn2)^2+...+(Cnn)^2=(2n!)/(n!)^2

    由这个式子再加上组合数的一些定理可得(反正我是不会证的)

      ans=(2n)!*(n!)^(mod-2)%mod

      其中(n!)^(mod-2)即为(n!)^2在mod下的逆元,所以除法变为乘法

    然后在我们了解了公式之后打一个(2n)!的表,然后每次算完%一下mod

    然后套个快速幂即可,数据过多可以再套个快读快写

    T2-
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 long long n,T;
     4 const long long modd=1e9+7;
     5 long long dis[2000010],x[2000010];
     6 long long ans,ak,ac,wa;
     7 long long ksm(long long a, long long b, long long p){
     8      long long ret=1;
     9      while(b){
    10          if(b%2)ret=(ret*a)%p;
    11          a=(a*a)%p;
    12          b=b>>1;
    13      }
    14      return ret;
    15 }
    16 inline int read(){
    17     int X=0; bool flag=1; char ch=getchar();
    18     while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
    19     while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
    20     if(flag) return X;
    21     return ~(X-1);
    22 }
    23 inline int write(long long X){
    24     if(X<0) {putchar('-'); X=~(X-1);}
    25     int s[20],top=0;
    26     while(X) {s[++top]=X%10; X/=10;}
    27     if(!top) s[++top]=0;
    28     while(top) putchar(s[top--]+'0');
    29 }
    30 int main(){
    31     T=read();
    32     dis[0]=x[0]=1;
    33     for(register int i=1;i<=2000000;i++) dis[i]=dis[i-1]*i%modd;
    34     while(T--)
    35     {
    36         n=read();
    37         wa=ksm(dis[n],modd-2,modd);
    38         ans=dis[2*n]*wa%modd*wa%modd;
    39         write(ans);
    40         putchar('
    ');
    41     }
    42     return 0;
    43 }
    排列组合

       T3

      考试时我竟然想用线段树做!!(快停止这危险的想法),难度中上

    其实本题正解是带有dp色彩的模拟...

      思路:首先咱们可以发现一个回文字符串的性质,假设咱们有一字符串长度>=3

    假设它左右端点的字符相同,那显然内侧也是一个回文串,其次我们很显然的发现只

    有一个字符的串是回文串,然后长度为2的字符串只需要特判一下就可以确定是否为

    回文串了,验证回文串算法get√

      其次我们为什么称这道题为带有dp色彩的模拟呢?显然我们可以先O(n)处理一遍长度为1和长度为2的字符串,然后我即可找到dp式 dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1];

    非常优秀!而dp结束后我们只需要再判断整合后的字符串是否满足回文串即可

    T3-
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 long long T,n;
     4 int l,r;
     5 int a[5010][5010];
     6 bool vis[5010][5010];
     7 char s[100010];
     8 bool check(int L,int R){
     9     if(vis[L][R]) return true;
    10     else if(s[L]==s[R]) return check(L+1,R-1); 
    11     return false;
    12 }
    13 int main(){
    14     cin>>s+1;
    15     int len=strlen(s+1);
    16     scanf("%lld",&T);
    17     for(register int i=1;i<=len;i++){
    18         vis[i][i]=true;
    19         a[i][i]++;
    20         a[i][i+1]=2;
    21         if(s[i]==s[i+1]) a[i][i+1]++,vis[i][i+1]=true;
    22     }
    23     for(register int i=3;i<=len;i++){
    24         for(register int l=1;l+i-1<=len;l++){
    25             int r=l+i-1;
    26             a[l][r]=a[l][r-1]+a[l+1][r]-a[l+1][r-1];
    27             if(check(l,r)) a[l][r]++,vis[l][r]=true;
    28         }
    29     }
    30     while(T--){
    31         int num1,num2;
    32         scanf("%d%d",&l,&r);
    33         printf("%d
    ",a[l][r]);
    34     }
    35     return 0;
    36 }
    回文

      end;

  • 相关阅读:
    VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)转
    转载 获取管理员权限
    Linux端图形处理工具ImageMagick在Centos上的安装
    JQUERY 的AJAX只执行一次问题
    ASP.NET项目常见错误信息:HRESULT:0x800736B1
    存储过程(我们简称SP)的编写和优化
    sql server中扩展存储过程大全
    Range对象基本操作应用示例(2)
    让IIS支持DZ和PW的伪静态方法
    js日期时间函数(经典+完善+实用)
  • 原文地址:https://www.cnblogs.com/liuhailin/p/11017278.html
Copyright © 2011-2022 走看看