zoukankan      html  css  js  c++  java
  • 中国(北方)大学生程序设计训练赛(第二周) (A B D G)

    比赛链接

    A题是KMP,先把A拼接到B的后面,然后利用next数组的意义(包括其具体含义,以及失配时的应用),得到ans

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 char T[200005],S[200005];
     5 int tlen,slen;
     6 int Next[200005];
     7 
     8 void getNext()
     9 {
    10     int j=0,k=-1;
    11     Next[0]=-1;
    12     while(j<tlen)
    13         if(k==-1||T[j]==T[k])
    14             Next[++j]=++k;
    15         else
    16             k=Next[k];
    17 }
    18 
    19 int cal(int x)
    20 {
    21     int ret=0;
    22     while(Next[x]!=-1)
    23     {
    24         x=Next[x];
    25         ret++;
    26     }
    27     return ret;
    28 }
    29 
    30 int main()
    31 {
    32     //freopen("test.txt","r",stdin);
    33     int TT;scanf("%d",&TT);
    34     while(TT--)
    35     {
    36         scanf("%s%s",S,T);
    37         int x=min(strlen(S),strlen(T));
    38         strcat(T,S);
    39         tlen=strlen(T);
    40         getNext();
    41         int len=min(Next[tlen],x);
    42         int t=cal(len);
    43         printf("%d
    ",t);
    44         
    45     }
    46 }
    A

    B算是数学题吧,对于同一个数,如果是整数,怎样操作都不会对difference有影响,而取ceil和取floor则恰好使difference差1,想明白这点就好了

    代码自己没写,贴个链接。。 http://blog.csdn.net/mz839555819/article/details/47844275

    D是DP,转移方程见代码

    假设:当i'<i时,dp[i']都是确定好的最小的消耗值
    1.当i为偶数时,dp[i]可能来自三个方向:i-1,i+1,i/2。若来自i+1,则i+1必然来自i+2,下面比较来自i+2和来自i/2的两种情况。
        dp[i]<-dp[i+2]+2x<-dp[(i+2)/2]+y+2x<-(dp[i/2]-x,dp[i/2]+x)+y+2x ;
        dp[i]<-dp[i/2]+y
    显然后者得到的dp[i]更小,故i为偶数情况下,只可能从两个方向转移过来
    2.当i为奇数时,dp[i]可能来自两个个方向:i-1,i+1。而i-1,i+1都是偶数,这样借用上面的偶数情况下的结论就可以了,即dp[i+1]只能由自己或是dp[(i+1)/2]转移过来。其中由dp[i]转移的情况推给dp[i-1]就好了

    转移方程如下
      if(i&1) dp[i]=min(dp[i-1]+x,dp[(i+1)/2]+x+y)
      else dp[i]=min(dp[i-1]+x,dp[i/2]+y)

    //最后,哪里有问题的话,欢迎提出来~
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 LL n,x,y,ans;
     6 LL dp[10000007];
     7 
     8 int main()
     9 {
    10     //freopen("test.txt","r",stdin);
    11     while(cin>>n>>x>>y)
    12     {
    13         memset(dp,0x3f3f3f3f,sizeof(dp));
    14         ans=0;
    15         dp[1]=x;dp[0]=0;
    16         for(int i=2;i<=n+1;i++)
    17         {
    18             if(i&1)
    19                 dp[i]=min(dp[i-1]+x,dp[(i+1)/2]+x+y);
    20             else
    21                 dp[i]=min(dp[i-1]+x,dp[i/2]+y);
    22         }
    23         cout<<dp[n]<<endl;
    24     }
    25 }
    D

    G题并查集,不同节点构成连通分量数 在这里等于 不同质因子的构成连通分量数。

    具体一些细节: 1是特例; 只有质因子存在于图中时才要考虑该质因子

    p.s. 分解质因数,素数筛 心里存个固定的板子真心好~

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long LL;
      4 
      5 const int N=1e6+3;
      6 int not_prime[N+5];
      7 vector<int> prime;
      8 bool vis[N+5];        //图中存在label,使i是label的质因数 
      9 bool done[N+5];        //这一连通分量是否已被计数 
     10 int p[N+5];
     11 int T,kase;
     12 
     13 int Find(int x)
     14 {
     15     return x==p[x]? x:p[x]=Find(p[x]);
     16 }
     17 void Union(int x,int y)
     18 {
     19     x=Find(x),y=Find(y);
     20     p[x]=y;
     21 }
     22 
     23 void init()
     24 {
     25     for(int i=2;i<=N;i++)
     26     {
     27         if(!not_prime[i])
     28         {
     29             //printf("%d=====
    ",i);
     30             prime.push_back(i);
     31             for(LL j=(LL)i*i;j<=N;j+=i)
     32                 not_prime[j]=true;
     33         }
     34     }
     35 }
     36 int init1()
     37 {
     38     for(int i=1;i<=N;i++)
     39         p[i]=i;
     40     memset(vis,false,sizeof(vis));
     41     memset(done,false,sizeof(done));
     42 }
     43 
     44 void getFactors(int x)
     45 {
     46     vector<int> a;
     47     for(int i=0;prime[i]*prime[i]<=x;i++)
     48     {
     49         if(x%prime[i]==0)
     50         {
     51             a.push_back(prime[i]),vis[prime[i]]=true;
     52             while(x%prime[i]==0) x/=prime[i];
     53         }
     54     }
     55     if(x>1) a.push_back(x),vis[x]=true;
     56     for(int i=1;i<a.size();i++)
     57         Union(a[0],a[i]);
     58 }
     59 
     60 int solve()
     61 {
     62     int ret=0;
     63     for(int i=0;i<prime.size();i++)
     64     {
     65         if(vis[prime[i]])
     66         {
     67             int t=Find(prime[i]);
     68             if(!done[t])
     69             {
     70                 ret++;
     71                 //printf("===%d====",t);
     72                 done[t]=true;
     73             }
     74         }
     75     }
     76     return ret;
     77 }
     78 
     79 int main()
     80 {
     81     init();
     82     //freopen("test.txt","r",stdin);
     83     scanf("%d",&T);
     84     while(T--)
     85     {
     86         init1();
     87         int ans=0; 
     88         int n;
     89         scanf("%d",&n);
     90         for(int i=0;i<n;i++)
     91         {
     92             int t;
     93             scanf("%d",&t);
     94             if(t==1)
     95             {
     96                 ans++;
     97                 continue; 
     98             }
     99             getFactors(t);
    100         }
    101         ans+=solve();
    102         printf("Case %d: %d
    ",++kase,ans);
    103     }
    104 }
    G
  • 相关阅读:
    五子棋人机对战设计
    通过getSystemServices获取手机管理大全
    C#常见错误解决方法
    🍖数据增删改查页面搭建
    🍖django ORM 表关系与django 请求生命周期流程图
    🍖django ORM 简介
    🍖Python与django连接数据库
    🍖静态文件配置与request对象
    开启进程的两种方式
    进程PID 与PPID
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/6538388.html
Copyright © 2011-2022 走看看