爆炸的一场
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(); } }
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; }
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); } }
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; }