Codeforces Round #625

A. Contest for Robots(模拟+贪心)
计算第一家公司可以跑第二家公司不能跑的关卡。如果是0答案为-1;否则如果第一家可以跑的总关卡数目比第二家多,答案为1,如果小于等于第二家答案为 第二家+1-第一家/第一家可以二第二家不可以 向上取正。

#include<cstdio>
#include<iostream>
using namespace std;
int p1[102];
int p2[102];
int n;
int s1;
int s2;
int d;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&p1[i]);
		s1+=p1[i]; 
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&p2[i]);
		s2+=p2[i]; 
	} 
	if(s2<s1){
		printf("1\n");
	}else{
		for(int i=1;i<=n;i++){
			if(p1[i]==1&&p2[i]!=1){
				d++;
			}
		}
		if(d==0){
			printf("-1");
		}else{
			int ans=s2+d-s1+1;
			if(ans%d==0)
			printf("%d\n",ans/d);
			else printf("%d\n",(ans/d)+1);
		}
	} 
	return 0;
} 

B. Journey Planning(桶)
分组然后找最大,分组规则:按c[i]-i的值分组,相同的可以相通;用桶记录每一组的个数;分组计算。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int a[200005];
int buk[800005];
long long cnt[800005];
long long ans;
const int maxn=200005;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		a[i]-=i; 
		buk[maxn+a[i]]++;
	}
	for(int i=1;i<=n;i++){
		cnt[maxn+a[i]]+=i;
	}
	for(int i=0;i<=800005;i++){
		ans=max(ans,cnt[i]+(long long)buk[i]*(i-maxn));
	}
	printf("%lld\n",ans);
	return 0;
}

C. Remove Adjacent(链表+贪心)
实现字符删除用链表,删除后面的字母对较小的字母没有影响所以选择贪心。

#include<cstdio>
#include<iostream>
using namespace std;
struct node{
	int ch;
	node * pre;
	node * next;
	node(){
		
	}
}; 
node * beginn=new node();
node * endd=new node();
long long ans;
long long n;
void insert(node * p,int x){
	endd=new node();
	p->next=endd;
	p->ch=x;
	endd->next=NULL;
	endd->pre=p;
	endd->ch=-1;
}
void del(node * p){
	p->pre->next=p->next;
	p->next->pre=p->pre;
	delete p;
}
void opr(int u){
	node *i=beginn->next;
	while(i!=endd){
		if(i->ch==u&&((i->pre->ch==i->ch-1)||(i->next->ch==i->ch-1))){
			ans++;
			node * u=i;
			i=i->next;
			del(u);
		}else{
			i=i->next;
		}
		
	}
}
void print(){
	node * i=beginn->next;
	while(i!=endd){
		printf("%d ",i->ch);
		i=i->next;
	}
	printf("\n");
}
int main(){
	cin>>n;
	beginn->next=endd;
	endd->pre=beginn;
	beginn->ch=-1;
	endd->ch=-1;
	for(int i=1;i<=n;i++){
		char c;
		cin>>c;
		insert(endd,c-'a'+1);
	}
    for(int i=26;i>=1;i--){
		for(int j=1;j<=n;j++)
		opr(i);
		//print();
	}
	cout<<ans<<endl;
	return 0;
}

D. Navigation System(最短路)
反向建图,bfs求最短路,并记录不同从目的地到i最短路dis[i]的数量cnt[i]。计算固定路径上,一个节点与前一个节点的最短路看看是否满足的dis[i]=dis[i-1]+1:如果满足并且cnt[i]>1maxm++;否则maxm++,minm++;

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=200005;
struct node{
	int i;
	int d;
	node(int a,int b):i(a),d(b){
	}
	node(){
	}
};
struct Edge{
	int from;
	int to;
	Edge(){
	}
	Edge(int a,int b):from(a),to(b){
		
	}
}Edges[maxn];
vector<int>G[maxn];
int t;
void addEdge(int a,int b){
	Edges[t]=Edge(a,b);
	G[a].push_back(t);
	t++;
}
int vis[maxn];
int dis[maxn];
int cnt[maxn];
int n,m;
int k;
int p[maxn];
void bfs(int u){
	queue<node>Q;
	while(!Q.empty())Q.pop();
	Q.push(node(u,0));dis[u]=0;	vis[u]=1;
	while(!Q.empty()){
		node &o=Q.front();Q.pop();
		for(int j=0;j<G[o.i].size();j++){
			if(!vis[Edges[G[o.i][j]].to]){
				dis[Edges[G[o.i][j]].to]=o.d+1;
				Q.push(node(Edges[G[o.i][j]].to,o.d+1));
				cnt[Edges[G[o.i][j]].to]=1;
				vis[Edges[G[o.i][j]].to]=1;
			}else{
				if(o.d+1==dis[Edges[G[o.i][j]].to])cnt[Edges[G[o.i][j]].to]++;
			}
		}
	}
}
long long maxm,minm;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		addEdge(b,a);
	}
	scanf("%d",&k);
	for(int i=1;i<=k;i++){
		scanf("%d",&p[i]);
	}
	bfs(p[k]);
	/*for(int i=1;i<=n;i++){
		printf("%d ",dis[i]);
	}
	
	for(int i=1;i<=n;i++){
		printf("%d ",cnt[i]);
	}*/
	for(int i=1;i<=k;i++){
	
		if(i>1){
			if(dis[p[i-1]]!=1+dis[p[i]]){
				maxm++;
				minm++;
			}else{
				if(cnt[p[i-1]]>1){
					maxm++;
				}
			} 
		}
	}
	cout<<minm<<" "<<maxm<<endl;
	return 0;
}

待补:

D. Navigation System(线段树or分块)
E. World of Darkraft: Battle for Azathoth(字符串哈希+线段树)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值