Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2)

链接:http://codeforces.com/contest/738

A题:水题

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n;
char s[maxn];

int main(){
	//freopen("in.txt","r",stdin);
	while(cin>>n>>(s+1)){
		for(int i=1;i<=n;){
			int j=i+1;
			if(j+1<=n&&s[i]=='o'&&s[j]=='g'&&s[j+1]=='o'){
				while(j+1<=n&&s[j]=='g'&&s[j+1]=='o') j+=2;
				s[i]=s[i+1]=s[i+2]='*';
				for(int k=i+3;k<j;k++) s[k]='#';
			}
			i=j;
		}
//		cout<<(s+1)<<endl;
		for(int i=1;i<=n;i++) if(s[i]!='#') printf("%c",s[i]);puts("");
	}
	return 0;
}
B题:水题

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn=1100;
const int INF=1e9+10;

int n,m;
int a[maxn][maxn];
int L[maxn],R[maxn],D[maxn],U[maxn];

int main(){
	//freopen("in.txt","r",stdin);
	while(cin>>n>>m){
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
				scanf("%d",&a[i][j]);
		for(int i=1;i<=n;i++){
			L[i]=m+1;R[i]=0;
			for(int j=1;j<=m;j++){
				if(!a[i][j]) continue;
				L[i]=min(L[i],j);
				R[i]=max(R[i],j);
			}
		}
		for(int j=1;j<=m;j++){
			U[j]=n+1;D[j]=0;
			for(int i=1;i<=n;i++){
				if(!a[i][j]) continue;
				U[j]=min(U[j],i);
				D[j]=max(D[j],i);
			}
		}
		int res=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(!a[i][j]) res+=(L[i]<j)+(R[i]>j)+(U[j]<i)+(D[j]>i);
			}
		}
		cout<<res<<endl;
	}
	return 0;
}
C题:水题,二分

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;
const double EPS=1e-10;

struct Node{
	int c,v;
	friend bool operator<(Node A,Node B){
		return A.c==B.c?A.v>B.v:A.c<B.c;
	}
};Node p[maxn];
int n,k,s,t;
int g[maxn];

ll get(int v,int d){
	if(v<d) return -1;
	int v2=2*(v-d);
	if(v2>d*2) v2=d*2;
	int rest=d-v2/2;
	int v1=max(0,rest);
	return 2LL*v1+v2/2;
}

bool check(int v){
	ll tt=0;
	for(int i=1;i<=k;i++){
		int d=g[i]-g[i-1];
		ll tmp=get(v,d);
		if(tmp==-1) return 0;
		tt+=tmp;
		if(tt>t) return 0;
	}
	return 1;
}

int bin(int l,int r){
	int id=INF;
	while(l<=r){
		int m=(l+r)>>1;
		if(check(p[m].v)) id=min(id,m),r=m-1;
		else l=m+1;
	}
	if(id==INF) return -1;
	return p[id].c;
}

int main(){
//	freopen("in.txt","r",stdin);
	while(cin>>n>>k>>s>>t){
		for(int i=1;i<=n;i++) scanf("%d%d",&p[i].c,&p[i].v);
		for(int i=1;i<=k;i++) scanf("%d",&g[i]);
		g[0]=0;
		g[++k]=s;
		sort(g,g+k+1);
		sort(p+1,p+n+1);
		int pn=1;
		for(int i=2;i<=n;i++){
			if(p[i].v<=p[pn].v) continue;
			p[++pn]=p[i];
		}
		printf("%d\n",bin(1,pn));
	}
	return 0;
}
D题:水题,贪心

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,a,b,k;
char s[maxn];
struct Node{
	int len,cnt;
	int l,r;
	friend bool operator<(Node A,Node B){
		return A.len<B.len;
	}
};Node p[maxn];int pn;
int ans[maxn],ansn;

void solve(int l,int r,int c){
	int len=r-l+1;
	if(len<2*b-1) ans[++ansn]=l+b-1;
	else{
		int cnt=len/b;
		for(int i=l+b-1;i<=r;i+=b){
			ans[++ansn]=i;
			cnt--;
			if(cnt<c) break;
		}
	}
}


int main(){
//	freopen("in.txt","r",stdin);
	while(cin>>n>>a>>b>>k){
		scanf("%s",s+1);
		pn=0;
		for(int i=1;i<=n;){
			if(s[i]=='0'){
				int j=i+1;
				while(j<=n&&s[j]=='0') j++;
				if(j-i>=b) p[++pn].len=j-i,p[pn].l=i,p[pn].r=j-1;
				i=j;
			}
			else i++;
		}
		sort(p+1,p+pn+1);
		int ta=a;
		for(int i=1;i<=pn;i++){
			int c=p[i].len/b;
			if(c<=ta) p[i].cnt=c,ta-=c;
			else p[i].cnt=ta,ta=0;
		}
		ansn=0;
		for(int i=pn;i>=1;i--){
			solve(p[i].l,p[i].r,p[i].cnt);
			if(p[i].cnt) break;
		}
		printf("%d\n",ansn);
		for(int i=1;i<=ansn;i++) printf("%d ",ans[i]);puts("");
	}
	return 0;
}

E题:水题,给一颗有根树,给定每个结点的祖先结点的数量序列,求使得序列合法的最小改变。首先明确合法的序列是:有且只有一个0,排序之后序列相邻数之差<=1。因此只要把其它的0设为INF,然后排序,从前往后贪心,用后面的来填前面的空位就好了,用链表模拟一下就可以了。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,a[maxn],s;
int val[maxn],L[maxn],R[maxn];
int tot,rt;

int newnode(int v){
	++tot;
	val[tot]=v;
	L[tot]=R[tot]=0;
	return tot;
}

void link(int l,int r){
	R[l]=r;L[r]=l;
}

int main(){
	//freopen("in.txt","r",stdin);
	while(cin>>n>>s){
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		int res=0;
		if(a[s]) a[s]=0,res=1;
		sort(a+1,a+n+1);
		for(int i=2;i<=n;i++) if(!a[i]) a[i]=INF;
		sort(a+1,a+n+1);
		tot=0;
		rt=newnode(a[1]);
		for(int i=2;i<=n;i++){
		   	int p=newnode(a[i]);
			link(tot-1,p);
		}
		int l=rt,r=tot;
		while(l!=r){
			if(val[R[l]]<=val[l]+1) l=R[l];
			else{
				int p=r;
				r=L[r];R[r]=0;
				link(p,R[l]);
				link(l,p);
				val[p]=val[l]+1;
				res++;
				if(l==r) break;
				l=R[l];
			}
		}
		if(val[r]>val[l]+1) res++;
		cout<<res<<endl;
	}
	return 0;
}
F题:博弈dp,样例没看懂。。留坑待补。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值