集训队选拔赛 day4

  爆炸的一场

A:

题意:给定一个原串 a  其顺序是固定的   求多少个原串能组成目标串b   (原串可以进行删除一些数 )

和之前南昌网络赛的字符串题一模一样 

那题是先预处理 nex 位置  然后进行不断的跳  

不过这题用这种方法会超时    (那题有多个子串  速度很快  )

正解:  将位置加入到vector  不断进行二分查找即可  

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=1e6+10;
int a[N],b[N];
int n,m,cnt,pos,ok,ans;

map<int,int>mp;
vector<int>table[N];
int main()
{
    vector<int>::iterator it;
    int cas;RI(cas);
    while(cas--)
    {
        RII(n,m);
        cnt=0,ok=1;
        rep(i,1,n){
            RI(a[i]);
            if(!mp[a[i]])mp[a[i]]=++cnt;
        }

        rep(i,1,m){
            RI(b[i]);if(!mp[b[i]])ok=0;
        }
        if(!ok){
            printf("-1
");mp.clear();continue;
        }

        rep(i,1,n){
            table[mp[a[i]]].push_back(i);
        }

        int ans=1,now=table[mp[b[1]]][0];

        rep(i,2,m){
            
            
            it=upper_bound(table[mp[b[i]]].begin(),table[mp[b[i]]].end(),now);
            if(it==table[mp[b[i]]].end())
            ans++,now=table[mp[b[i]]][0];
            else now=*it ;
        }
        
        printf("%d
",ans);

        rep(i,1,cnt)
        table[i].clear();


        mp.clear();
    }

}
View Code

C:

题意:给定n个机器人  每个机器人身上有q个接口 每个接口有其成本  问将这n个机器人连成一个整体的最小成本  ( 接口与接口相连 )

n个机器人要连接n-1次   所以要选择 2*(n-1)个接口 

但是单纯的选择最小的2*(n-1) 是不够的   可能会出现 某些机器人没有被连上的情况 ( 同时 如果接口数小于2*(n-1)  显然不成立)

所以每个机器人选择一个最小的     然后再选择其余的  2*(n-1)-n 个即可

很简单的贪心  比赛的时候没想出来很可惜

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s)
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=1e6+10;
int n,m,cnt,k,Q;
int a[N];
vector<int>q;

int main()
{
    int cas;RI(cas);
    while(cas--)
    {
        q.clear();cnt=0;
        RI(n);
        ll ans=0;
        rep(i,1,n){
            RI(Q);cnt+=Q;
            rep(j,1,Q)RI(a[j]);
            sort(a+1,a+1+Q);
            ans+=a[1];
            rep(j,2,Q)q.push_back(a[j]);
        }
        if(cnt<2*(n-1)){printf("-1");continue;}
        cnt=2*(n-1)-n;
        sort(q.begin(),q.end());
        rep(i,0,cnt-1)
        ans+=q[i];
        printf("%lld
",ans);
        q.clear();
    }

    return 0;
}
View Code

E:

题意:  

给出x y z 求整个三角形的面积   

用相似三角形推出公式即可   比赛的时候因为impossible 的情况wa了好几发

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=1e5+10;
ll x,y,z;
ll ans1,ans2;
int main()
{

    int cas;RI(cas);
    while(cas--)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        ans1=x*(y+z)*y+y*(x+z)*x;
        ans2=(x+z)*(y+z)-x*(y+z)-y*(x+z);
        if(ans2<=0)
        {
           printf("Impossible
");
           continue;
        }

        ll t=__gcd(ans1,ans2);
        ans1/=t;ans2/=t;
        ans1+=(x+z+y)*ans2;
        double s=(double)ans1/(double) ans2;
        if(s>1e16)
        printf("Impossible
");
        else
        printf("%lld %lld
",ans1,ans2);
    }
}
View Code

H:

给定1-n的网络流   求将其扩容到最大流C 时增加的最小容量

之前做过原题, 不过加inf 会超时   改小一点就过了

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=2000+10;

ll maxflow,mincost;
int last[N],pre[N],dis[N],flow[N],C;
bool vis[N];
struct Edge{
    int next,to,flow,dis;
}edge[N<<2];
int pos=1,head[N<<2];
void init()
{
    pos=1;
    CLR(head,0);
    mincost=maxflow=0;
}
queue <int> q;
void add(int from,int to,int flow,int dis)//flow流量 dis费用
{
    edge[++pos].next=head[from];
    edge[pos].flow=flow;
    edge[pos].dis=dis;
    edge[pos].to=to;
    head[from]=pos;

    edge[++pos].next=head[to];
    edge[pos].flow=0;
    edge[pos].dis=-dis;
    edge[pos].to=from;
    head[to]=pos;

}
bool spfa(int s,int t)
{
    CLR(dis,0x3f);
    CLR(flow,0x3f);
    CLR(vis,0);
    while (!q.empty()) q.pop();
    dis[s]=0; pre[t]=-1; q.push(s); vis[s]=1;
    int tot=0;
    while (!q.empty())
    {
        int now=q.front(); q.pop(); vis[now]=0;
        for (int i=head[now]; i; i=edge[i].next)
        {
            int to=edge[i].to;
            if  (edge[i].flow>0 && dis[to]>dis[now]+edge[i].dis)
            {
                dis[to]=edge[i].dis+dis[now];
                flow[to]=min(edge[i].flow,flow[now]);
                last[to]=i;
                pre[to]=now;
                if (!vis[to])
                {
                    q.push(to); vis[to]=1;
                }
            }
        }
    }
    return pre[t]!=-1;
}
void MCMF(int s,int t)
{
    while (spfa(s,t))
    {
        int now=t;
        maxflow+=flow[t];
        mincost+=flow[t]*dis[t];
        while (now!=s)
        {
            edge[last[now]].flow-=flow[t];//dis . flow
            edge[last[now]^1].flow+=flow[t];
            now=pre[now];
        }
    }
}
int n,m,s,t,a,b,c;
int main()
{
    int cas;RI(cas);
    while(cas--)
    {
        init();
        RIII(n,m,C);
        t=n+1;s=1;
        rep(i,1,m)
        {
            RIII(a,b,c);
            add(a,b,c,0);
            add(a,b,1000,1);
        }
        add(n,t,C,0);
        MCMF(s,t);
        printf("%d
",mincost);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/11158969.html