您的位置:首页 > 其它

浙大 4月月赛

2016-04-12 16:35 351 查看
zoj3929

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define N 100005
const int MOD=1000000007;
typedef long long ll;
int two
;
int pos
;
int tree
;
int n;

inline int lowbit(int x){
return x&(-x);
}
void add(int x,int y){
for(int i=x;i<=n;i+=lowbit(i)){
tree[i]+=y;
if(tree[i]>=MOD) tree[i]-=MOD;
}
}
int sum(int x){
int an=0;
for(int i=x;i>=1;i-=lowbit(i)){
an+=tree[i];
if(an>=MOD) an-=MOD;
}
return an;
}
int main(){
int T;
int i,j,k;
scanf("%d",&T);
two[0]=1; for(i=1;i<=100000;i++) two[i]=(two[i-1]*2)%MOD;
while(T--){
ll ans=0;
scanf("%d",&n);
memset(tree,0,sizeof(tree));
for(i=1;i<=n;i++) scanf("%d",&pos[i]);
for(i=1;i<=n;i++){
ans=( ans+(ll)( sum(n)-sum(pos[i])+MOD )*two[n-i] )%MOD;
ans=( ans+(ll)( sum(pos[i]-1) )*two[n-i] )%MOD;
if(i==1) add(pos[i],2);
else add(pos[i],two[i-1]);
}
printf("%lld\n",ans);
}
return 0;
}
/*
【题意】
一个双端队列 依次将带标号的球等概率从左或右放入
求 xi > xi+1 的i的数量 的方案数

【做法】
树状数组维护
每次加上该球
1.从左边进入 恰好它旁边的球比它小的方案数
2.从右边进入 恰好它旁边的球比它大的方案数
【思考】

*/


zoj3930

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
const int MOD =1000000007;
typedef long long ll;
char t[2005];
char a[2005];
vector<char> vc;
int cn;
int main(){
int T;
int i,j,k;
int cn;
scanf("%d",&T); getchar();
while(T--){
vc.clear();
gets(t); int len=strlen(t);
for(i=0;i<len;i++){
if( t[i]==' ' || t[i]=='\t' ) continue;
else if( t[i]>='0' && t[i]<='9' ) vc.push_back(t[i]);
else if(t[i]=='d'){
for(cn=0,j=i+1;j<len;j++){
if( t[j]>='0' && t[j]<='9' ) a[cn++]=t[j];
else break;
}
a[cn]='\0';
i=j-1;
ll tmp=0;
for(j=0;j<vc.size();j++){
tmp=tmp*10+vc[j]-'0';
} vc.clear();
if(tmp<=1) {
printf("[d%s]",a);
}else {
printf("(");
while(tmp--){
printf("[d%s]",a);
if(tmp) printf(" + ");
}
printf(")");
}
}else if( t[i]=='+' || t[i]=='*' || t[i]=='-' || t[i]=='/' ){
for(j=0;j<vc.size();j++) printf("%c",vc[j]); vc.clear();
printf(" %c ",t[i]);
}else {
for(j=0;j<vc.size();j++) printf("%c",vc[j]); vc.clear();
printf("%c",t[i]);
}
}
for(j=0;j<vc.size();j++) printf("%c",vc[j]); vc.clear();
printf(" = [Result]\n");
}
return 0;
}
/*
【题意】
将一段字符串进行处理
1.删去空格和tab键('\t') 坑点
2.将3d5转换为[d5] + [d5] + [d5]
3.在运算符两边加上空格
【做法】
模拟 注意'\t'坑点

【思考】
比赛时应该耐心看完每个题 这个题之前没人做 最后才被人发现是水题

*/


zoj3931

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
int S;
int F[150];
map<ll,int> mp[2];
map<ll,int>::iterator it;
priority_queue<int,vector<int>,greater<int> >Q;
struct Node{
ll l,r;
}tree[150];
int main(){
int T;
int i,j,k;
ll target;
scanf("%d",&T);
while(T--){
while(!Q.empty()) Q.pop();
for(i=0;i<2;i++) mp[i].clear();
scanf("%d",&S);
for(i=0;i<S;i++) scanf("%d",&F[i]);
scanf("%lld",&target);
for(i=0;i<S;i++) {
Q.push(F[i]);
}
int cn1=0;
while(Q.size()>1){
int t1=Q.top(); Q.pop();
int t2=Q.top(); Q.pop();
Q.push(t1+t2);
tree[++cn1].l=t1; tree[cn1].r=t2;
}
int flag=1;
mp[flag][tree[1].l]=1; mp[flag][tree[1].r]=1;
for(i=2;i<=cn1;i++){
mp[flag^1].clear();
for(it=mp[flag].begin();it!=mp[flag].end();it++){
ll t1=it->first;
if( t1+tree[i].l<=target ) mp[flag^1][t1+tree[i].l]=1;
if( t1+tree[i].r<=target ) mp[flag^1][t1+tree[i].r]=1;
}
flag^=1;
}
if(mp[flag][target]) printf("Yes\n");
else printf("No\n");
}
return 0;
}、
/*
【题意】
对于给出的序列进行哈夫曼建树
求是否有方案树满足  每个数的编码中 0 的个数合为 E

【做法】
模拟

【思考】
这个题当时也是没时间看 全卡在那道zkw费用流上了

*/


zoj3933

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MAXN=505;
const int MAXM=250005;
const int INF=0x3f3f3f3f;
struct Edge{
int to,next,cap,flow,cost;
Edge(int _to=0,int _next=0,int _cap=0,int _flow=0,int _cost=0):
to(_to),next(_next),cap(_cap),flow(_flow),cost(_cost){}
}edge[MAXM];
vector<pair<int,int> > vc;
struct ZKW_MinCostMaxFlow{
int head[MAXN],tot;
int cur[MAXN];
int dis[MAXN];
bool vis[MAXN];
int ss,tt,N;
int min_cost,max_flow;
void init(){
tot=0;
vc.clear();
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,int cost){
edge[tot]=Edge(v,head[u],cap,0,cost);
head[u]=tot++;
edge[tot]=Edge(u,head[v],0,0,-cost);
head[v]=tot++;
}
int aug(int u,int flow){
if(u==tt) return flow;
vis[u]=true;
for(int i=cur[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if( edge[i].cap>edge[i].flow && !vis[v] && dis[u]==dis[v]+edge[i].cost ){
int tmp=aug(v,min(flow,edge[i].cap-edge[i].flow));
edge[i].flow+=tmp;
edge[i^1].flow-=tmp;
cur[u]=i;
if(tmp) return tmp;
}
}
return 0;
}
bool modify_label(){
int d=INF;
for(int u=0;u<N;u++){
if(vis[u])
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(edge[i].cap>edge[i].flow && !vis[v])
d=min(d,dis[v]+edge[i].cost-dis[u]);
}
}
if(d==INF) return false;
for(int i=0;i<N;i++)
if(vis[i]){
vis[i]=false;
dis[i]+=d;
}
return true;
}
void mincostmaxflow(int start,int ed,int n){
ss=start,tt=ed,N=n;
min_cost=max_flow=0;
for(int i=0;i<n;i++) dis[i]=0;
while(1){
for(int i=0;i<n;i++) cur[i]=head[i];
while(1){
for(int i=0;i<n;i++) vis[i]=false;
int tmp=aug(ss,INF);
if(tmp==0) break;
max_flow+=tmp;
min_cost+=tmp*dis[ss];
}
if(!modify_label()) break;
}
printf("%d %d\n",max_flow,2*max_flow-min_cost);
}
void prin(int x,int y){
int i,j;
for(i=1;i<=x;i++){
for(j=head[i];j!=-1;j=edge[j].next){
if(edge[j].flow==1){
vc.push_back(make_pair(i,edge[j].to)); break;
}
}
}
}
}solve;
char s1[505];
char s2[505];
int num[505];
int pre[505];
int bad[505][505];
int main(){
int T;
int n;
int i,j,k;
scanf("%d",&T);
while(T--){
solve.init();
memset(bad,0,sizeof(bad));
int a1=0; int a2=0;
scanf("%d %s %s",&n,&s1,&s2);
for(i=0;s1[i];i++){
if(s1[i]=='1') a1++;
else a2++;
}
int b1=0; int b2=a1;
for(i=0;s1[i];i++){
if(s1[i]=='1') num[i]=++b1,pre[b1]=i;
else num[i]=++b2,pre[b2]=i;
}
for(i=0;i<n;i++){
int a,b; scanf("%d",&a);
for(j=0;j<a;j++){
scanf("%d",&b); bad[i][b-1]=1;
}
}
for(i=0;i<n;i++)
for(j=i+1;j<n;j++){
if(bad[i][j]==0){
int t1=num[i]; int t2=num[j];
if(s1[i]==s1[j]) continue;
if(t1>t2) swap(t1,t2);
solve.addedge( t1,t2,1,(s2[i]=='1')+(s2[j]=='1') );
}
}
for(i=1;i<=a1;i++) solve.addedge(0,i,1,0);
for(i=a1+1;i<=n;i++) solve.addedge(i,n+1,1,0);
solve.mincostmaxflow(0,n+1,n+2);
solve.prin(a1,n);
for(i=0;i<vc.size();i++){
int t1=vc[i].first; int t2=vc[i].second;
printf("%d %d\n",pre[t1]+1,pre[t2]+1);
}
}
return 0;
}
/*
【题意】
有两组人 给出他们的性别和各自不喜欢的人
要求从两组各选出一个人成为一队
求最多能组成的队数 以及最多的女生的情况

【做法】
zkw费用流 用KM以及SPFA被卡的不要不要的
两组放两边 二分建图
【思考】

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: